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,*,*,alu_reg,load2,store2")
65 (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
66 (set_attr "length" "4,4,4,4,4,4,8,8,8")
67 (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*")
68 (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*")
69 (set_attr "neg_pool_range" "*,*,*,1004,*,*,*,1004,*")])
71 (define_insn "*neon_mov<mode>"
72 [(set (match_operand:VQXMOV 0 "nonimmediate_operand"
73 "=w,Un,w, w, ?r,?w,?r,?r, ?Us")
74 (match_operand:VQXMOV 1 "general_operand"
75 " w,w, Dn,Uni, w, r, r, Usi, r"))]
77 && (register_operand (operands[0], <MODE>mode)
78 || register_operand (operands[1], <MODE>mode))"
80 if (which_alternative == 2)
83 static char templ[40];
85 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
86 &operands[1], &width);
88 gcc_assert (is_valid != 0);
91 return "vmov.f32\t%q0, %1 @ <mode>";
93 sprintf (templ, "vmov.i%d\t%%q0, %%1 @ <mode>", width);
98 switch (which_alternative)
100 case 0: return "vmov\t%q0, %q1 @ <mode>";
101 case 1: case 3: return output_move_neon (operands);
102 case 2: gcc_unreachable ();
103 case 4: return "vmov\t%Q0, %R0, %e1 @ <mode>\;vmov\t%J0, %K0, %f1";
104 case 5: return "vmov\t%e0, %Q1, %R1 @ <mode>\;vmov\t%f0, %J1, %K1";
105 default: return output_move_quad (operands);
108 [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\
109 neon_mrrc,neon_mcr_2_mcrr,*,*,*")
110 (set_attr "type" "*,*,*,*,*,*,alu_reg,load4,store4")
111 (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
112 (set_attr "length" "4,8,4,8,8,8,16,8,16")
113 (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*")
114 (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*")
115 (set_attr "neg_pool_range" "*,*,*,996,*,*,*,996,*")])
117 (define_expand "movti"
118 [(set (match_operand:TI 0 "nonimmediate_operand" "")
119 (match_operand:TI 1 "general_operand" ""))]
122 if (can_create_pseudo_p ())
124 if (!REG_P (operands[0]))
125 operands[1] = force_reg (TImode, operands[1]);
129 (define_expand "mov<mode>"
130 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "")
131 (match_operand:VSTRUCT 1 "general_operand" ""))]
134 if (can_create_pseudo_p ())
136 if (!REG_P (operands[0]))
137 operands[1] = force_reg (<MODE>mode, operands[1]);
141 (define_insn "*neon_mov<mode>"
142 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "=w,Ut,w")
143 (match_operand:VSTRUCT 1 "general_operand" " w,w, Ut"))]
145 && (register_operand (operands[0], <MODE>mode)
146 || register_operand (operands[1], <MODE>mode))"
148 switch (which_alternative)
151 case 1: case 2: return output_move_neon (operands);
152 default: gcc_unreachable ();
155 [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_ldm_2")
156 (set (attr "length") (symbol_ref "arm_attr_length_move_neon (insn)"))])
159 [(set (match_operand:EI 0 "s_register_operand" "")
160 (match_operand:EI 1 "s_register_operand" ""))]
161 "TARGET_NEON && reload_completed"
162 [(set (match_dup 0) (match_dup 1))
163 (set (match_dup 2) (match_dup 3))]
165 int rdest = REGNO (operands[0]);
166 int rsrc = REGNO (operands[1]);
169 dest[0] = gen_rtx_REG (TImode, rdest);
170 src[0] = gen_rtx_REG (TImode, rsrc);
171 dest[1] = gen_rtx_REG (DImode, rdest + 4);
172 src[1] = gen_rtx_REG (DImode, rsrc + 4);
174 neon_disambiguate_copy (operands, dest, src, 2);
178 [(set (match_operand:OI 0 "s_register_operand" "")
179 (match_operand:OI 1 "s_register_operand" ""))]
180 "TARGET_NEON && reload_completed"
181 [(set (match_dup 0) (match_dup 1))
182 (set (match_dup 2) (match_dup 3))]
184 int rdest = REGNO (operands[0]);
185 int rsrc = REGNO (operands[1]);
188 dest[0] = gen_rtx_REG (TImode, rdest);
189 src[0] = gen_rtx_REG (TImode, rsrc);
190 dest[1] = gen_rtx_REG (TImode, rdest + 4);
191 src[1] = gen_rtx_REG (TImode, rsrc + 4);
193 neon_disambiguate_copy (operands, dest, src, 2);
197 [(set (match_operand:CI 0 "s_register_operand" "")
198 (match_operand:CI 1 "s_register_operand" ""))]
199 "TARGET_NEON && reload_completed"
200 [(set (match_dup 0) (match_dup 1))
201 (set (match_dup 2) (match_dup 3))
202 (set (match_dup 4) (match_dup 5))]
204 int rdest = REGNO (operands[0]);
205 int rsrc = REGNO (operands[1]);
208 dest[0] = gen_rtx_REG (TImode, rdest);
209 src[0] = gen_rtx_REG (TImode, rsrc);
210 dest[1] = gen_rtx_REG (TImode, rdest + 4);
211 src[1] = gen_rtx_REG (TImode, rsrc + 4);
212 dest[2] = gen_rtx_REG (TImode, rdest + 8);
213 src[2] = gen_rtx_REG (TImode, rsrc + 8);
215 neon_disambiguate_copy (operands, dest, src, 3);
219 [(set (match_operand:XI 0 "s_register_operand" "")
220 (match_operand:XI 1 "s_register_operand" ""))]
221 "TARGET_NEON && reload_completed"
222 [(set (match_dup 0) (match_dup 1))
223 (set (match_dup 2) (match_dup 3))
224 (set (match_dup 4) (match_dup 5))
225 (set (match_dup 6) (match_dup 7))]
227 int rdest = REGNO (operands[0]);
228 int rsrc = REGNO (operands[1]);
231 dest[0] = gen_rtx_REG (TImode, rdest);
232 src[0] = gen_rtx_REG (TImode, rsrc);
233 dest[1] = gen_rtx_REG (TImode, rdest + 4);
234 src[1] = gen_rtx_REG (TImode, rsrc + 4);
235 dest[2] = gen_rtx_REG (TImode, rdest + 8);
236 src[2] = gen_rtx_REG (TImode, rsrc + 8);
237 dest[3] = gen_rtx_REG (TImode, rdest + 12);
238 src[3] = gen_rtx_REG (TImode, rsrc + 12);
240 neon_disambiguate_copy (operands, dest, src, 4);
243 (define_expand "movmisalign<mode>"
244 [(set (match_operand:VDQX 0 "neon_struct_or_register_operand")
245 (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_or_register_operand")]
246 UNSPEC_MISALIGNED_ACCESS))]
247 "TARGET_NEON && !BYTES_BIG_ENDIAN"
249 /* This pattern is not permitted to fail during expansion: if both arguments
250 are non-registers (e.g. memory := constant, which can be created by the
251 auto-vectorizer), force operand 1 into a register. */
252 if (!s_register_operand (operands[0], <MODE>mode)
253 && !s_register_operand (operands[1], <MODE>mode))
254 operands[1] = force_reg (<MODE>mode, operands[1]);
257 (define_insn "*movmisalign<mode>_neon_store"
258 [(set (match_operand:VDX 0 "neon_struct_operand" "=Um")
259 (unspec:VDX [(match_operand:VDX 1 "s_register_operand" " w")]
260 UNSPEC_MISALIGNED_ACCESS))]
261 "TARGET_NEON && !BYTES_BIG_ENDIAN"
262 "vst1.<V_sz_elem>\t{%P1}, %A0"
263 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
265 (define_insn "*movmisalign<mode>_neon_load"
266 [(set (match_operand:VDX 0 "s_register_operand" "=w")
267 (unspec:VDX [(match_operand:VDX 1 "neon_struct_operand" " Um")]
268 UNSPEC_MISALIGNED_ACCESS))]
269 "TARGET_NEON && !BYTES_BIG_ENDIAN"
270 "vld1.<V_sz_elem>\t{%P0}, %A1"
271 [(set_attr "neon_type" "neon_vld1_1_2_regs")])
273 (define_insn "*movmisalign<mode>_neon_store"
274 [(set (match_operand:VQX 0 "neon_struct_operand" "=Um")
275 (unspec:VQX [(match_operand:VQX 1 "s_register_operand" " w")]
276 UNSPEC_MISALIGNED_ACCESS))]
277 "TARGET_NEON && !BYTES_BIG_ENDIAN"
278 "vst1.<V_sz_elem>\t{%q1}, %A0"
279 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
281 (define_insn "*movmisalign<mode>_neon_load"
282 [(set (match_operand:VQX 0 "s_register_operand" "=w")
283 (unspec:VQX [(match_operand:VQX 1 "neon_struct_operand" " Um")]
284 UNSPEC_MISALIGNED_ACCESS))]
285 "TARGET_NEON && !BYTES_BIG_ENDIAN"
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" "nota8,*,*,onlya8,*,*,*")]
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" "nota8,*,*,*,onlya8")]
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 (define_insn "iordi3_neon"
683 [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r,?w,?w")
684 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r,w,0")
685 (match_operand:DI 2 "neon_logic_op2" "w,Dl,r,r,w,Dl")))]
688 switch (which_alternative)
690 case 0: /* fall through */
691 case 4: return "vorr\t%P0, %P1, %P2";
692 case 1: /* fall through */
693 case 5: return neon_output_logic_immediate ("vorr", &operands[2],
694 DImode, 0, VALID_NEON_QREG_MODE (DImode));
697 default: gcc_unreachable ();
700 [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,neon_int_1,neon_int_1")
701 (set_attr "length" "*,*,8,8,*,*")
702 (set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")]
705 ;; The concrete forms of the Neon immediate-logic instructions are vbic and
706 ;; vorr. We support the pseudo-instruction vand instead, because that
707 ;; corresponds to the canonical form the middle-end expects to use for
708 ;; immediate bitwise-ANDs.
710 (define_insn "and<mode>3"
711 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
712 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
713 (match_operand:VDQ 2 "neon_inv_logic_op2" "w,DL")))]
716 switch (which_alternative)
718 case 0: return "vand\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
719 case 1: return neon_output_logic_immediate ("vand", &operands[2],
720 <MODE>mode, 1, VALID_NEON_QREG_MODE (<MODE>mode));
721 default: gcc_unreachable ();
724 [(set_attr "neon_type" "neon_int_1")]
727 (define_insn "anddi3_neon"
728 [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r,?w,?w")
729 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r,w,0")
730 (match_operand:DI 2 "neon_inv_logic_op2" "w,DL,r,r,w,DL")))]
733 switch (which_alternative)
735 case 0: /* fall through */
736 case 4: return "vand\t%P0, %P1, %P2";
737 case 1: /* fall through */
738 case 5: return neon_output_logic_immediate ("vand", &operands[2],
739 DImode, 1, VALID_NEON_QREG_MODE (DImode));
742 default: gcc_unreachable ();
745 [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,neon_int_1,neon_int_1")
746 (set_attr "length" "*,*,8,8,*,*")
747 (set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")]
750 (define_insn "orn<mode>3_neon"
751 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
752 (ior:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
753 (match_operand:VDQ 1 "s_register_operand" "w")))]
755 "vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
756 [(set_attr "neon_type" "neon_int_1")]
759 ;; TODO: investigate whether we should disable
760 ;; this and bicdi3_neon for the A8 in line with the other
762 (define_insn_and_split "orndi3_neon"
763 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r")
764 (ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,0,0,r"))
765 (match_operand:DI 1 "s_register_operand" "w,r,r,0")))]
773 (TARGET_NEON && !(IS_VFP_REGNUM (REGNO (operands[0]))))"
774 [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
775 (set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))]
780 operands[3] = gen_highpart (SImode, operands[0]);
781 operands[0] = gen_lowpart (SImode, operands[0]);
782 operands[4] = gen_highpart (SImode, operands[2]);
783 operands[2] = gen_lowpart (SImode, operands[2]);
784 operands[5] = gen_highpart (SImode, operands[1]);
785 operands[1] = gen_lowpart (SImode, operands[1]);
789 emit_insn (gen_one_cmpldi2 (operands[0], operands[2]));
790 emit_insn (gen_iordi3 (operands[0], operands[1], operands[0]));
794 [(set_attr "neon_type" "neon_int_1,*,*,*")
795 (set_attr "length" "*,16,8,8")
796 (set_attr "arch" "any,a,t2,t2")]
799 (define_insn "bic<mode>3_neon"
800 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
801 (and:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
802 (match_operand:VDQ 1 "s_register_operand" "w")))]
804 "vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
805 [(set_attr "neon_type" "neon_int_1")]
808 ;; Compare to *anddi_notdi_di.
809 (define_insn "bicdi3_neon"
810 [(set (match_operand:DI 0 "s_register_operand" "=w,?=&r,?&r")
811 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0"))
812 (match_operand:DI 1 "s_register_operand" "w,0,r")))]
818 [(set_attr "neon_type" "neon_int_1,*,*")
819 (set_attr "length" "*,8,8")]
822 (define_insn "xor<mode>3"
823 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
824 (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
825 (match_operand:VDQ 2 "s_register_operand" "w")))]
827 "veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
828 [(set_attr "neon_type" "neon_int_1")]
831 (define_insn "xordi3_neon"
832 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w")
833 (xor:DI (match_operand:DI 1 "s_register_operand" "%w,0,r,w")
834 (match_operand:DI 2 "s_register_operand" "w,r,r,w")))]
841 [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1")
842 (set_attr "length" "*,8,8,*")
843 (set_attr "arch" "nota8,*,*,onlya8")]
846 (define_insn "one_cmpl<mode>2"
847 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
848 (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
850 "vmvn\t%<V_reg>0, %<V_reg>1"
851 [(set_attr "neon_type" "neon_int_1")]
854 (define_insn "abs<mode>2"
855 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
856 (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
858 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
859 [(set (attr "neon_type")
860 (if_then_else (match_test "<Is_float_mode>")
861 (if_then_else (match_test "<Is_d_reg>")
862 (const_string "neon_fp_vadd_ddd_vabs_dd")
863 (const_string "neon_fp_vadd_qqq_vabs_qq"))
864 (const_string "neon_int_3")))]
867 (define_insn "neg<mode>2"
868 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
869 (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
871 "vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
872 [(set (attr "neon_type")
873 (if_then_else (match_test "<Is_float_mode>")
874 (if_then_else (match_test "<Is_d_reg>")
875 (const_string "neon_fp_vadd_ddd_vabs_dd")
876 (const_string "neon_fp_vadd_qqq_vabs_qq"))
877 (const_string "neon_int_3")))]
880 (define_insn "negdi2_neon"
881 [(set (match_operand:DI 0 "s_register_operand" "=&w, w,r,&r")
882 (neg:DI (match_operand:DI 1 "s_register_operand" " w, w,0, r")))
883 (clobber (match_scratch:DI 2 "= X,&w,X, X"))
884 (clobber (reg:CC CC_REGNUM))]
887 [(set_attr "length" "8")]
890 ; Split negdi2_neon for vfp registers
892 [(set (match_operand:DI 0 "s_register_operand" "")
893 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
894 (clobber (match_scratch:DI 2 ""))
895 (clobber (reg:CC CC_REGNUM))]
896 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
897 [(set (match_dup 2) (const_int 0))
898 (parallel [(set (match_dup 0) (minus:DI (match_dup 2) (match_dup 1)))
899 (clobber (reg:CC CC_REGNUM))])]
901 if (!REG_P (operands[2]))
902 operands[2] = operands[0];
906 ; Split negdi2_neon for core registers
908 [(set (match_operand:DI 0 "s_register_operand" "")
909 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
910 (clobber (match_scratch:DI 2 ""))
911 (clobber (reg:CC CC_REGNUM))]
912 "TARGET_32BIT && reload_completed
913 && arm_general_register_operand (operands[0], DImode)"
914 [(parallel [(set (match_dup 0) (neg:DI (match_dup 1)))
915 (clobber (reg:CC CC_REGNUM))])]
919 (define_insn "*umin<mode>3_neon"
920 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
921 (umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
922 (match_operand:VDQIW 2 "s_register_operand" "w")))]
924 "vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
925 [(set_attr "neon_type" "neon_int_5")]
928 (define_insn "*umax<mode>3_neon"
929 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
930 (umax:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
931 (match_operand:VDQIW 2 "s_register_operand" "w")))]
933 "vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
934 [(set_attr "neon_type" "neon_int_5")]
937 (define_insn "*smin<mode>3_neon"
938 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
939 (smin:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
940 (match_operand:VDQW 2 "s_register_operand" "w")))]
942 "vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
943 [(set (attr "neon_type")
944 (if_then_else (match_test "<Is_float_mode>")
945 (const_string "neon_fp_vadd_ddd_vabs_dd")
946 (const_string "neon_int_5")))]
949 (define_insn "*smax<mode>3_neon"
950 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
951 (smax:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
952 (match_operand:VDQW 2 "s_register_operand" "w")))]
954 "vmax.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
955 [(set (attr "neon_type")
956 (if_then_else (match_test "<Is_float_mode>")
957 (const_string "neon_fp_vadd_ddd_vabs_dd")
958 (const_string "neon_int_5")))]
961 ; TODO: V2DI shifts are current disabled because there are bugs in the
962 ; generic vectorizer code. It ends up creating a V2DI constructor with
965 (define_insn "vashl<mode>3"
966 [(set (match_operand:VDQIW 0 "s_register_operand" "=w,w")
967 (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w,w")
968 (match_operand:VDQIW 2 "imm_lshift_or_reg_neon" "w,Dn")))]
971 switch (which_alternative)
973 case 0: return "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
974 case 1: return neon_output_shift_immediate ("vshl", 'i', &operands[2],
976 VALID_NEON_QREG_MODE (<MODE>mode),
978 default: gcc_unreachable ();
981 [(set (attr "neon_type")
982 (if_then_else (match_test "<Is_d_reg>")
983 (const_string "neon_vshl_ddd")
984 (const_string "neon_shift_3")))]
987 (define_insn "vashr<mode>3_imm"
988 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
989 (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
990 (match_operand:VDQIW 2 "imm_for_neon_rshift_operand" "Dn")))]
993 return neon_output_shift_immediate ("vshr", 's', &operands[2],
994 <MODE>mode, VALID_NEON_QREG_MODE (<MODE>mode),
997 [(set (attr "neon_type")
998 (if_then_else (match_test "<Is_d_reg>")
999 (const_string "neon_vshl_ddd")
1000 (const_string "neon_shift_3")))]
1003 (define_insn "vlshr<mode>3_imm"
1004 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1005 (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1006 (match_operand:VDQIW 2 "imm_for_neon_rshift_operand" "Dn")))]
1009 return neon_output_shift_immediate ("vshr", 'u', &operands[2],
1010 <MODE>mode, VALID_NEON_QREG_MODE (<MODE>mode),
1013 [(set (attr "neon_type")
1014 (if_then_else (match_test "<Is_d_reg>")
1015 (const_string "neon_vshl_ddd")
1016 (const_string "neon_shift_3")))]
1019 ; Used for implementing logical shift-right, which is a left-shift by a negative
1020 ; amount, with signed operands. This is essentially the same as ashl<mode>3
1021 ; above, but using an unspec in case GCC tries anything tricky with negative
1024 (define_insn "ashl<mode>3_signed"
1025 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
1026 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
1027 (match_operand:VDQI 2 "s_register_operand" "w")]
1028 UNSPEC_ASHIFT_SIGNED))]
1030 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1031 [(set (attr "neon_type")
1032 (if_then_else (match_test "<Is_d_reg>")
1033 (const_string "neon_vshl_ddd")
1034 (const_string "neon_shift_3")))]
1037 ; Used for implementing logical shift-right, which is a left-shift by a negative
1038 ; amount, with unsigned operands.
1040 (define_insn "ashl<mode>3_unsigned"
1041 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
1042 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
1043 (match_operand:VDQI 2 "s_register_operand" "w")]
1044 UNSPEC_ASHIFT_UNSIGNED))]
1046 "vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1047 [(set (attr "neon_type")
1048 (if_then_else (match_test "<Is_d_reg>")
1049 (const_string "neon_vshl_ddd")
1050 (const_string "neon_shift_3")))]
1053 (define_expand "vashr<mode>3"
1054 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1055 (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1056 (match_operand:VDQIW 2 "imm_rshift_or_reg_neon" "")))]
1059 if (s_register_operand (operands[2], <MODE>mode))
1061 rtx neg = gen_reg_rtx (<MODE>mode);
1062 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1063 emit_insn (gen_ashl<mode>3_signed (operands[0], operands[1], neg));
1066 emit_insn (gen_vashr<mode>3_imm (operands[0], operands[1], operands[2]));
1070 (define_expand "vlshr<mode>3"
1071 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1072 (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1073 (match_operand:VDQIW 2 "imm_rshift_or_reg_neon" "")))]
1076 if (s_register_operand (operands[2], <MODE>mode))
1078 rtx neg = gen_reg_rtx (<MODE>mode);
1079 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1080 emit_insn (gen_ashl<mode>3_unsigned (operands[0], operands[1], neg));
1083 emit_insn (gen_vlshr<mode>3_imm (operands[0], operands[1], operands[2]));
1089 ;; This pattern loads a 32-bit shift count into a 64-bit NEON register,
1090 ;; leaving the upper half uninitalized. This is OK since the shift
1091 ;; instruction only looks at the low 8 bits anyway. To avoid confusing
1092 ;; data flow analysis however, we pretend the full register is set
1094 (define_insn "neon_load_count"
1095 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
1096 (unspec:DI [(match_operand:SI 1 "nonimmediate_operand" "Um,r")]
1097 UNSPEC_LOAD_COUNT))]
1100 vld1.32\t{%P0[0]}, %A1
1101 vmov.32\t%P0[0], %1"
1102 [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")]
1105 (define_insn "ashldi3_neon_noclobber"
1106 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
1107 (ashift:DI (match_operand:DI 1 "s_register_operand" " w,w")
1108 (match_operand:DI 2 "reg_or_int_operand" " i,w")))]
1109 "TARGET_NEON && reload_completed
1110 && (!CONST_INT_P (operands[2])
1111 || (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 64))"
1113 vshl.u64\t%P0, %P1, %2
1114 vshl.u64\t%P0, %P1, %P2"
1115 [(set_attr "neon_type" "neon_vshl_ddd,neon_vshl_ddd")]
1118 (define_insn_and_split "ashldi3_neon"
1119 [(set (match_operand:DI 0 "s_register_operand" "= w, w,?&r,?r, ?w,w")
1120 (ashift:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, r, 0w,w")
1121 (match_operand:SI 2 "general_operand" "rUm, i, r, i,rUm,i")))
1122 (clobber (match_scratch:SI 3 "= X, X,?&r, X, X,X"))
1123 (clobber (match_scratch:SI 4 "= X, X,?&r, X, X,X"))
1124 (clobber (match_scratch:DI 5 "=&w, X, X, X, &w,X"))
1125 (clobber (reg:CC_C CC_REGNUM))]
1128 "TARGET_NEON && reload_completed"
1132 if (IS_VFP_REGNUM (REGNO (operands[0])))
1134 if (CONST_INT_P (operands[2]))
1136 if (INTVAL (operands[2]) < 1)
1138 emit_insn (gen_movdi (operands[0], operands[1]));
1141 else if (INTVAL (operands[2]) > 63)
1142 operands[2] = gen_rtx_CONST_INT (VOIDmode, 63);
1146 emit_insn (gen_neon_load_count (operands[5], operands[2]));
1147 operands[2] = operands[5];
1150 /* Ditch the unnecessary clobbers. */
1151 emit_insn (gen_ashldi3_neon_noclobber (operands[0], operands[1],
1156 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
1157 /* This clobbers CC. */
1158 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
1160 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
1161 operands[2], operands[3], operands[4]);
1165 [(set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")
1166 (set_attr "opt" "*,*,speed,speed,*,*")]
1169 ; The shift amount needs to be negated for right-shifts
1170 (define_insn "signed_shift_di3_neon"
1171 [(set (match_operand:DI 0 "s_register_operand" "=w")
1172 (unspec:DI [(match_operand:DI 1 "s_register_operand" " w")
1173 (match_operand:DI 2 "s_register_operand" " w")]
1174 UNSPEC_ASHIFT_SIGNED))]
1175 "TARGET_NEON && reload_completed"
1176 "vshl.s64\t%P0, %P1, %P2"
1177 [(set_attr "neon_type" "neon_vshl_ddd")]
1180 ; The shift amount needs to be negated for right-shifts
1181 (define_insn "unsigned_shift_di3_neon"
1182 [(set (match_operand:DI 0 "s_register_operand" "=w")
1183 (unspec:DI [(match_operand:DI 1 "s_register_operand" " w")
1184 (match_operand:DI 2 "s_register_operand" " w")]
1185 UNSPEC_ASHIFT_UNSIGNED))]
1186 "TARGET_NEON && reload_completed"
1187 "vshl.u64\t%P0, %P1, %P2"
1188 [(set_attr "neon_type" "neon_vshl_ddd")]
1191 (define_insn "ashrdi3_neon_imm_noclobber"
1192 [(set (match_operand:DI 0 "s_register_operand" "=w")
1193 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" " w")
1194 (match_operand:DI 2 "const_int_operand" " i")))]
1195 "TARGET_NEON && reload_completed
1196 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64"
1197 "vshr.s64\t%P0, %P1, %2"
1198 [(set_attr "neon_type" "neon_vshl_ddd")]
1201 (define_insn "lshrdi3_neon_imm_noclobber"
1202 [(set (match_operand:DI 0 "s_register_operand" "=w")
1203 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" " w")
1204 (match_operand:DI 2 "const_int_operand" " i")))]
1205 "TARGET_NEON && reload_completed
1206 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64"
1207 "vshr.u64\t%P0, %P1, %2"
1208 [(set_attr "neon_type" "neon_vshl_ddd")]
1213 (define_insn_and_split "<shift>di3_neon"
1214 [(set (match_operand:DI 0 "s_register_operand" "= w, w,?&r,?r,?w,?w")
1215 (rshifts:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, r,0w, w")
1216 (match_operand:SI 2 "reg_or_int_operand" " r, i, r, i, r, i")))
1217 (clobber (match_scratch:SI 3 "=2r, X, &r, X,2r, X"))
1218 (clobber (match_scratch:SI 4 "= X, X, &r, X, X, X"))
1219 (clobber (match_scratch:DI 5 "=&w, X, X, X,&w, X"))
1220 (clobber (reg:CC CC_REGNUM))]
1223 "TARGET_NEON && reload_completed"
1227 if (IS_VFP_REGNUM (REGNO (operands[0])))
1229 if (CONST_INT_P (operands[2]))
1231 if (INTVAL (operands[2]) < 1)
1233 emit_insn (gen_movdi (operands[0], operands[1]));
1236 else if (INTVAL (operands[2]) > 64)
1237 operands[2] = gen_rtx_CONST_INT (VOIDmode, 64);
1239 /* Ditch the unnecessary clobbers. */
1240 emit_insn (gen_<shift>di3_neon_imm_noclobber (operands[0],
1246 /* We must use a negative left-shift. */
1247 emit_insn (gen_negsi2 (operands[3], operands[2]));
1248 emit_insn (gen_neon_load_count (operands[5], operands[3]));
1249 emit_insn (gen_<shifttype>_shift_di3_neon (operands[0], operands[1],
1255 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
1256 /* This clobbers CC. */
1257 emit_insn (gen_arm_<shift>di3_1bit (operands[0], operands[1]));
1259 /* This clobbers CC (ASHIFTRT by register only). */
1260 arm_emit_coreregs_64bit_shift (<CODE>, operands[0], operands[1],
1261 operands[2], operands[3], operands[4]);
1266 [(set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")
1267 (set_attr "opt" "*,*,speed,speed,*,*")]
1270 ;; Widening operations
1272 (define_insn "widen_ssum<mode>3"
1273 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1274 (plus:<V_widen> (sign_extend:<V_widen>
1275 (match_operand:VW 1 "s_register_operand" "%w"))
1276 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1278 "vaddw.<V_s_elem>\t%q0, %q2, %P1"
1279 [(set_attr "neon_type" "neon_int_3")]
1282 (define_insn "widen_usum<mode>3"
1283 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1284 (plus:<V_widen> (zero_extend:<V_widen>
1285 (match_operand:VW 1 "s_register_operand" "%w"))
1286 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1288 "vaddw.<V_u_elem>\t%q0, %q2, %P1"
1289 [(set_attr "neon_type" "neon_int_3")]
1292 ;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
1293 ;; shift-count granularity. That's good enough for the middle-end's current
1296 ;; Note that it's not safe to perform such an operation in big-endian mode,
1297 ;; due to element-ordering issues.
1299 (define_expand "vec_shr_<mode>"
1300 [(match_operand:VDQ 0 "s_register_operand" "")
1301 (match_operand:VDQ 1 "s_register_operand" "")
1302 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1303 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1306 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1307 const int width = GET_MODE_BITSIZE (<MODE>mode);
1308 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1309 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1310 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1312 if (num_bits == width)
1314 emit_move_insn (operands[0], operands[1]);
1318 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1319 operands[0] = gen_lowpart (bvecmode, operands[0]);
1320 operands[1] = gen_lowpart (bvecmode, operands[1]);
1322 emit_insn (gen_ext (operands[0], operands[1], zero_reg,
1323 GEN_INT (num_bits / BITS_PER_UNIT)));
1327 (define_expand "vec_shl_<mode>"
1328 [(match_operand:VDQ 0 "s_register_operand" "")
1329 (match_operand:VDQ 1 "s_register_operand" "")
1330 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1331 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1334 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1335 const int width = GET_MODE_BITSIZE (<MODE>mode);
1336 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1337 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1338 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1342 emit_move_insn (operands[0], CONST0_RTX (<MODE>mode));
1346 num_bits = width - num_bits;
1348 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1349 operands[0] = gen_lowpart (bvecmode, operands[0]);
1350 operands[1] = gen_lowpart (bvecmode, operands[1]);
1352 emit_insn (gen_ext (operands[0], zero_reg, operands[1],
1353 GEN_INT (num_bits / BITS_PER_UNIT)));
1357 ;; Helpers for quad-word reduction operations
1359 ; Add (or smin, smax...) the low N/2 elements of the N-element vector
1360 ; operand[1] to the high N/2 elements of same. Put the result in operand[0], an
1361 ; N/2-element vector.
1363 (define_insn "quad_halves_<code>v4si"
1364 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
1366 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
1367 (parallel [(const_int 0) (const_int 1)]))
1368 (vec_select:V2SI (match_dup 1)
1369 (parallel [(const_int 2) (const_int 3)]))))]
1371 "<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1"
1372 [(set_attr "vqh_mnem" "<VQH_mnem>")
1373 (set (attr "neon_type")
1374 (if_then_else (eq_attr "vqh_mnem" "vadd")
1375 (const_string "neon_int_1") (const_string "neon_int_5")))]
1378 (define_insn "quad_halves_<code>v4sf"
1379 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
1381 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
1382 (parallel [(const_int 0) (const_int 1)]))
1383 (vec_select:V2SF (match_dup 1)
1384 (parallel [(const_int 2) (const_int 3)]))))]
1385 "TARGET_NEON && flag_unsafe_math_optimizations"
1386 "<VQH_mnem>.f32\t%P0, %e1, %f1"
1387 [(set_attr "vqh_mnem" "<VQH_mnem>")
1388 (set (attr "neon_type")
1389 (if_then_else (eq_attr "vqh_mnem" "vadd")
1390 (const_string "neon_int_1") (const_string "neon_int_5")))]
1393 (define_insn "quad_halves_<code>v8hi"
1394 [(set (match_operand:V4HI 0 "s_register_operand" "+w")
1396 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
1397 (parallel [(const_int 0) (const_int 1)
1398 (const_int 2) (const_int 3)]))
1399 (vec_select:V4HI (match_dup 1)
1400 (parallel [(const_int 4) (const_int 5)
1401 (const_int 6) (const_int 7)]))))]
1403 "<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1"
1404 [(set_attr "vqh_mnem" "<VQH_mnem>")
1405 (set (attr "neon_type")
1406 (if_then_else (eq_attr "vqh_mnem" "vadd")
1407 (const_string "neon_int_1") (const_string "neon_int_5")))]
1410 (define_insn "quad_halves_<code>v16qi"
1411 [(set (match_operand:V8QI 0 "s_register_operand" "+w")
1413 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
1414 (parallel [(const_int 0) (const_int 1)
1415 (const_int 2) (const_int 3)
1416 (const_int 4) (const_int 5)
1417 (const_int 6) (const_int 7)]))
1418 (vec_select:V8QI (match_dup 1)
1419 (parallel [(const_int 8) (const_int 9)
1420 (const_int 10) (const_int 11)
1421 (const_int 12) (const_int 13)
1422 (const_int 14) (const_int 15)]))))]
1424 "<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1"
1425 [(set_attr "vqh_mnem" "<VQH_mnem>")
1426 (set (attr "neon_type")
1427 (if_then_else (eq_attr "vqh_mnem" "vadd")
1428 (const_string "neon_int_1") (const_string "neon_int_5")))]
1431 (define_expand "move_hi_quad_<mode>"
1432 [(match_operand:ANY128 0 "s_register_operand" "")
1433 (match_operand:<V_HALF> 1 "s_register_operand" "")]
1436 emit_move_insn (simplify_gen_subreg (<V_HALF>mode, operands[0], <MODE>mode,
1437 GET_MODE_SIZE (<V_HALF>mode)),
1442 (define_expand "move_lo_quad_<mode>"
1443 [(match_operand:ANY128 0 "s_register_operand" "")
1444 (match_operand:<V_HALF> 1 "s_register_operand" "")]
1447 emit_move_insn (simplify_gen_subreg (<V_HALF>mode, operands[0],
1453 ;; Reduction operations
1455 (define_expand "reduc_splus_<mode>"
1456 [(match_operand:VD 0 "s_register_operand" "")
1457 (match_operand:VD 1 "s_register_operand" "")]
1458 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1460 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1461 &gen_neon_vpadd_internal<mode>);
1465 (define_expand "reduc_splus_<mode>"
1466 [(match_operand:VQ 0 "s_register_operand" "")
1467 (match_operand:VQ 1 "s_register_operand" "")]
1468 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)
1469 && !BYTES_BIG_ENDIAN"
1471 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1472 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1474 emit_insn (gen_quad_halves_plus<mode> (step1, operands[1]));
1475 emit_insn (gen_reduc_splus_<V_half> (res_d, step1));
1476 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1481 (define_insn "reduc_splus_v2di"
1482 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1483 (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")]
1485 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1486 "vadd.i64\t%e0, %e1, %f1"
1487 [(set_attr "neon_type" "neon_int_1")]
1490 ;; NEON does not distinguish between signed and unsigned addition except on
1491 ;; widening operations.
1492 (define_expand "reduc_uplus_<mode>"
1493 [(match_operand:VDQI 0 "s_register_operand" "")
1494 (match_operand:VDQI 1 "s_register_operand" "")]
1495 "TARGET_NEON && (<Is_d_reg> || !BYTES_BIG_ENDIAN)"
1497 emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1]));
1501 (define_expand "reduc_smin_<mode>"
1502 [(match_operand:VD 0 "s_register_operand" "")
1503 (match_operand:VD 1 "s_register_operand" "")]
1504 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1506 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1507 &gen_neon_vpsmin<mode>);
1511 (define_expand "reduc_smin_<mode>"
1512 [(match_operand:VQ 0 "s_register_operand" "")
1513 (match_operand:VQ 1 "s_register_operand" "")]
1514 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)
1515 && !BYTES_BIG_ENDIAN"
1517 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1518 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1520 emit_insn (gen_quad_halves_smin<mode> (step1, operands[1]));
1521 emit_insn (gen_reduc_smin_<V_half> (res_d, step1));
1522 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1527 (define_expand "reduc_smax_<mode>"
1528 [(match_operand:VD 0 "s_register_operand" "")
1529 (match_operand:VD 1 "s_register_operand" "")]
1530 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1532 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1533 &gen_neon_vpsmax<mode>);
1537 (define_expand "reduc_smax_<mode>"
1538 [(match_operand:VQ 0 "s_register_operand" "")
1539 (match_operand:VQ 1 "s_register_operand" "")]
1540 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)
1541 && !BYTES_BIG_ENDIAN"
1543 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1544 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1546 emit_insn (gen_quad_halves_smax<mode> (step1, operands[1]));
1547 emit_insn (gen_reduc_smax_<V_half> (res_d, step1));
1548 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1553 (define_expand "reduc_umin_<mode>"
1554 [(match_operand:VDI 0 "s_register_operand" "")
1555 (match_operand:VDI 1 "s_register_operand" "")]
1558 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1559 &gen_neon_vpumin<mode>);
1563 (define_expand "reduc_umin_<mode>"
1564 [(match_operand:VQI 0 "s_register_operand" "")
1565 (match_operand:VQI 1 "s_register_operand" "")]
1566 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1568 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1569 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1571 emit_insn (gen_quad_halves_umin<mode> (step1, operands[1]));
1572 emit_insn (gen_reduc_umin_<V_half> (res_d, step1));
1573 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1578 (define_expand "reduc_umax_<mode>"
1579 [(match_operand:VDI 0 "s_register_operand" "")
1580 (match_operand:VDI 1 "s_register_operand" "")]
1583 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1584 &gen_neon_vpumax<mode>);
1588 (define_expand "reduc_umax_<mode>"
1589 [(match_operand:VQI 0 "s_register_operand" "")
1590 (match_operand:VQI 1 "s_register_operand" "")]
1591 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1593 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1594 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1596 emit_insn (gen_quad_halves_umax<mode> (step1, operands[1]));
1597 emit_insn (gen_reduc_umax_<V_half> (res_d, step1));
1598 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1603 (define_insn "neon_vpadd_internal<mode>"
1604 [(set (match_operand:VD 0 "s_register_operand" "=w")
1605 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1606 (match_operand:VD 2 "s_register_operand" "w")]
1609 "vpadd.<V_if_elem>\t%P0, %P1, %P2"
1610 ;; Assume this schedules like vadd.
1611 [(set (attr "neon_type")
1612 (if_then_else (match_test "<Is_float_mode>")
1613 (if_then_else (match_test "<Is_d_reg>")
1614 (const_string "neon_fp_vadd_ddd_vabs_dd")
1615 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1616 (const_string "neon_int_1")))]
1619 (define_insn "neon_vpsmin<mode>"
1620 [(set (match_operand:VD 0 "s_register_operand" "=w")
1621 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1622 (match_operand:VD 2 "s_register_operand" "w")]
1625 "vpmin.<V_s_elem>\t%P0, %P1, %P2"
1626 ;; Assume this schedules like vmin.
1627 [(set (attr "neon_type")
1628 (if_then_else (match_test "<Is_float_mode>")
1629 (const_string "neon_fp_vadd_ddd_vabs_dd")
1630 (const_string "neon_int_5")))]
1633 (define_insn "neon_vpsmax<mode>"
1634 [(set (match_operand:VD 0 "s_register_operand" "=w")
1635 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1636 (match_operand:VD 2 "s_register_operand" "w")]
1639 "vpmax.<V_s_elem>\t%P0, %P1, %P2"
1640 ;; Assume this schedules like vmax.
1641 [(set (attr "neon_type")
1642 (if_then_else (match_test "<Is_float_mode>")
1643 (const_string "neon_fp_vadd_ddd_vabs_dd")
1644 (const_string "neon_int_5")))]
1647 (define_insn "neon_vpumin<mode>"
1648 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1649 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1650 (match_operand:VDI 2 "s_register_operand" "w")]
1653 "vpmin.<V_u_elem>\t%P0, %P1, %P2"
1654 ;; Assume this schedules like umin.
1655 [(set_attr "neon_type" "neon_int_5")]
1658 (define_insn "neon_vpumax<mode>"
1659 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1660 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1661 (match_operand:VDI 2 "s_register_operand" "w")]
1664 "vpmax.<V_u_elem>\t%P0, %P1, %P2"
1665 ;; Assume this schedules like umax.
1666 [(set_attr "neon_type" "neon_int_5")]
1669 ;; Saturating arithmetic
1671 ; NOTE: Neon supports many more saturating variants of instructions than the
1672 ; following, but these are all GCC currently understands.
1673 ; FIXME: Actually, GCC doesn't know how to create saturating add/sub by itself
1674 ; yet either, although these patterns may be used by intrinsics when they're
1677 (define_insn "*ss_add<mode>_neon"
1678 [(set (match_operand:VD 0 "s_register_operand" "=w")
1679 (ss_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1680 (match_operand:VD 2 "s_register_operand" "w")))]
1682 "vqadd.<V_s_elem>\t%P0, %P1, %P2"
1683 [(set_attr "neon_type" "neon_int_4")]
1686 (define_insn "*us_add<mode>_neon"
1687 [(set (match_operand:VD 0 "s_register_operand" "=w")
1688 (us_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1689 (match_operand:VD 2 "s_register_operand" "w")))]
1691 "vqadd.<V_u_elem>\t%P0, %P1, %P2"
1692 [(set_attr "neon_type" "neon_int_4")]
1695 (define_insn "*ss_sub<mode>_neon"
1696 [(set (match_operand:VD 0 "s_register_operand" "=w")
1697 (ss_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1698 (match_operand:VD 2 "s_register_operand" "w")))]
1700 "vqsub.<V_s_elem>\t%P0, %P1, %P2"
1701 [(set_attr "neon_type" "neon_int_5")]
1704 (define_insn "*us_sub<mode>_neon"
1705 [(set (match_operand:VD 0 "s_register_operand" "=w")
1706 (us_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1707 (match_operand:VD 2 "s_register_operand" "w")))]
1709 "vqsub.<V_u_elem>\t%P0, %P1, %P2"
1710 [(set_attr "neon_type" "neon_int_5")]
1713 ;; Conditional instructions. These are comparisons with conditional moves for
1714 ;; vectors. They perform the assignment:
1716 ;; Vop0 = (Vop4 <op3> Vop5) ? Vop1 : Vop2;
1718 ;; where op3 is <, <=, ==, !=, >= or >. Operations are performed
1721 (define_expand "vcond<mode><mode>"
1722 [(set (match_operand:VDQW 0 "s_register_operand" "")
1724 (match_operator 3 "comparison_operator"
1725 [(match_operand:VDQW 4 "s_register_operand" "")
1726 (match_operand:VDQW 5 "nonmemory_operand" "")])
1727 (match_operand:VDQW 1 "s_register_operand" "")
1728 (match_operand:VDQW 2 "s_register_operand" "")))]
1729 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1731 HOST_WIDE_INT magic_word = (<MODE>mode == V2SFmode || <MODE>mode == V4SFmode)
1733 rtx magic_rtx = GEN_INT (magic_word);
1735 int swap_bsl_operands = 0;
1736 rtx mask = gen_reg_rtx (<V_cmp_result>mode);
1737 rtx tmp = gen_reg_rtx (<V_cmp_result>mode);
1739 rtx (*base_comparison) (rtx, rtx, rtx, rtx);
1740 rtx (*complimentary_comparison) (rtx, rtx, rtx, rtx);
1742 switch (GET_CODE (operands[3]))
1747 if (!REG_P (operands[5])
1748 && (operands[5] != CONST0_RTX (<MODE>mode)))
1749 operands[5] = force_reg (<MODE>mode, operands[5]);
1752 if (!REG_P (operands[5]))
1753 operands[5] = force_reg (<MODE>mode, operands[5]);
1756 switch (GET_CODE (operands[3]))
1766 base_comparison = gen_neon_vcge<mode>;
1767 complimentary_comparison = gen_neon_vcgt<mode>;
1775 base_comparison = gen_neon_vcgt<mode>;
1776 complimentary_comparison = gen_neon_vcge<mode>;
1781 base_comparison = gen_neon_vceq<mode>;
1782 complimentary_comparison = gen_neon_vceq<mode>;
1788 switch (GET_CODE (operands[3]))
1795 /* The easy case. Here we emit one of vcge, vcgt or vceq.
1796 As a LT b <=> b GE a && a LE b <=> b GT a. Our transformations are:
1804 emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx));
1806 emit_insn (complimentary_comparison (mask, operands[5], operands[4], magic_rtx));
1813 /* Vector compare returns false for lanes which are unordered, so if we use
1814 the inverse of the comparison we actually want to emit, then
1815 swap the operands to BSL, we will end up with the correct result.
1816 Note that a NE NaN and NaN NE b are true for all a, b.
1818 Our transformations are:
1823 a NE b -> !(a EQ b) */
1826 emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx));
1828 emit_insn (complimentary_comparison (mask, operands[5], operands[4], magic_rtx));
1830 swap_bsl_operands = 1;
1833 /* We check (a > b || b > a). combining these comparisons give us
1834 true iff !(a != b && a ORDERED b), swapping the operands to BSL
1835 will then give us (a == b || a UNORDERED b) as intended. */
1837 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5], magic_rtx));
1838 emit_insn (gen_neon_vcgt<mode> (tmp, operands[5], operands[4], magic_rtx));
1839 emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
1840 swap_bsl_operands = 1;
1843 /* Operands are ORDERED iff (a > b || b >= a).
1844 Swapping the operands to BSL will give the UNORDERED case. */
1845 swap_bsl_operands = 1;
1848 emit_insn (gen_neon_vcgt<mode> (tmp, operands[4], operands[5], magic_rtx));
1849 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4], magic_rtx));
1850 emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
1856 if (swap_bsl_operands)
1857 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1860 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1865 (define_expand "vcondu<mode><mode>"
1866 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1868 (match_operator 3 "arm_comparison_operator"
1869 [(match_operand:VDQIW 4 "s_register_operand" "")
1870 (match_operand:VDQIW 5 "s_register_operand" "")])
1871 (match_operand:VDQIW 1 "s_register_operand" "")
1872 (match_operand:VDQIW 2 "s_register_operand" "")))]
1876 int inverse = 0, immediate_zero = 0;
1878 mask = gen_reg_rtx (<V_cmp_result>mode);
1880 if (operands[5] == CONST0_RTX (<MODE>mode))
1882 else if (!REG_P (operands[5]))
1883 operands[5] = force_reg (<MODE>mode, operands[5]);
1885 switch (GET_CODE (operands[3]))
1888 emit_insn (gen_neon_vcge<mode> (mask, operands[4], operands[5],
1893 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5],
1898 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1904 emit_insn (gen_neon_vcle<mode> (mask, operands[4], operands[5],
1907 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4],
1913 emit_insn (gen_neon_vclt<mode> (mask, operands[4], operands[5],
1916 emit_insn (gen_neon_vcgt<mode> (mask, operands[5], operands[4],
1921 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1931 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1934 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1940 ;; Patterns for builtins.
1942 ; good for plain vadd, vaddq.
1944 (define_expand "neon_vadd<mode>"
1945 [(match_operand:VDQX 0 "s_register_operand" "=w")
1946 (match_operand:VDQX 1 "s_register_operand" "w")
1947 (match_operand:VDQX 2 "s_register_operand" "w")
1948 (match_operand:SI 3 "immediate_operand" "i")]
1951 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1952 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[2]));
1954 emit_insn (gen_neon_vadd<mode>_unspec (operands[0], operands[1],
1959 ; Note that NEON operations don't support the full IEEE 754 standard: in
1960 ; particular, denormal values are flushed to zero. This means that GCC cannot
1961 ; use those instructions for autovectorization, etc. unless
1962 ; -funsafe-math-optimizations is in effect (in which case flush-to-zero
1963 ; behaviour is permissible). Intrinsic operations (provided by the arm_neon.h
1964 ; header) must work in either case: if -funsafe-math-optimizations is given,
1965 ; intrinsics expand to "canonical" RTL where possible, otherwise intrinsics
1966 ; expand to unspecs (which may potentially limit the extent to which they might
1967 ; be optimized by generic code).
1969 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1971 (define_insn "neon_vadd<mode>_unspec"
1972 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1973 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1974 (match_operand:VDQX 2 "s_register_operand" "w")]
1977 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1978 [(set (attr "neon_type")
1979 (if_then_else (match_test "<Is_float_mode>")
1980 (if_then_else (match_test "<Is_d_reg>")
1981 (const_string "neon_fp_vadd_ddd_vabs_dd")
1982 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1983 (const_string "neon_int_1")))]
1986 ; operand 3 represents in bits:
1987 ; bit 0: signed (vs unsigned).
1988 ; bit 1: rounding (vs none).
1990 (define_insn "neon_vaddl<mode>"
1991 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1992 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1993 (match_operand:VDI 2 "s_register_operand" "w")
1994 (match_operand:SI 3 "immediate_operand" "i")]
1997 "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1998 [(set_attr "neon_type" "neon_int_3")]
2001 (define_insn "neon_vaddw<mode>"
2002 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2003 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
2004 (match_operand:VDI 2 "s_register_operand" "w")
2005 (match_operand:SI 3 "immediate_operand" "i")]
2008 "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
2009 [(set_attr "neon_type" "neon_int_2")]
2014 (define_insn "neon_vhadd<mode>"
2015 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2016 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2017 (match_operand:VDQIW 2 "s_register_operand" "w")
2018 (match_operand:SI 3 "immediate_operand" "i")]
2021 "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2022 [(set_attr "neon_type" "neon_int_4")]
2025 (define_insn "neon_vqadd<mode>"
2026 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2027 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2028 (match_operand:VDQIX 2 "s_register_operand" "w")
2029 (match_operand:SI 3 "immediate_operand" "i")]
2032 "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2033 [(set_attr "neon_type" "neon_int_4")]
2036 (define_insn "neon_vaddhn<mode>"
2037 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2038 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2039 (match_operand:VN 2 "s_register_operand" "w")
2040 (match_operand:SI 3 "immediate_operand" "i")]
2043 "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2"
2044 [(set_attr "neon_type" "neon_int_4")]
2047 ;; We cannot replace this unspec with mul<mode>3 because of the odd
2048 ;; polynomial multiplication case that can specified by operand 3.
2049 (define_insn "neon_vmul<mode>"
2050 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2051 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2052 (match_operand:VDQW 2 "s_register_operand" "w")
2053 (match_operand:SI 3 "immediate_operand" "i")]
2056 "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2057 [(set (attr "neon_type")
2058 (if_then_else (match_test "<Is_float_mode>")
2059 (if_then_else (match_test "<Is_d_reg>")
2060 (const_string "neon_fp_vadd_ddd_vabs_dd")
2061 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2062 (if_then_else (match_test "<Is_d_reg>")
2064 (match_test "<Scalar_mul_8_16>")
2065 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2066 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
2067 (if_then_else (match_test "<Scalar_mul_8_16>")
2068 (const_string "neon_mul_qqq_8_16_32_ddd_32")
2069 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
2072 (define_expand "neon_vmla<mode>"
2073 [(match_operand:VDQW 0 "s_register_operand" "=w")
2074 (match_operand:VDQW 1 "s_register_operand" "0")
2075 (match_operand:VDQW 2 "s_register_operand" "w")
2076 (match_operand:VDQW 3 "s_register_operand" "w")
2077 (match_operand:SI 4 "immediate_operand" "i")]
2080 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2081 emit_insn (gen_mul<mode>3add<mode>_neon (operands[0], operands[1],
2082 operands[2], operands[3]));
2084 emit_insn (gen_neon_vmla<mode>_unspec (operands[0], operands[1],
2085 operands[2], operands[3]));
2089 (define_expand "neon_vfma<VCVTF:mode>"
2090 [(match_operand:VCVTF 0 "s_register_operand")
2091 (match_operand:VCVTF 1 "s_register_operand")
2092 (match_operand:VCVTF 2 "s_register_operand")
2093 (match_operand:VCVTF 3 "s_register_operand")
2094 (match_operand:SI 4 "immediate_operand")]
2095 "TARGET_NEON && TARGET_FMA"
2097 emit_insn (gen_fma<mode>4_intrinsic (operands[0], operands[2], operands[3],
2102 (define_expand "neon_vfms<VCVTF:mode>"
2103 [(match_operand:VCVTF 0 "s_register_operand")
2104 (match_operand:VCVTF 1 "s_register_operand")
2105 (match_operand:VCVTF 2 "s_register_operand")
2106 (match_operand:VCVTF 3 "s_register_operand")
2107 (match_operand:SI 4 "immediate_operand")]
2108 "TARGET_NEON && TARGET_FMA"
2110 emit_insn (gen_fmsub<mode>4_intrinsic (operands[0], operands[2], operands[3],
2115 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2117 (define_insn "neon_vmla<mode>_unspec"
2118 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
2119 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
2120 (match_operand:VDQ 2 "s_register_operand" "w")
2121 (match_operand:VDQ 3 "s_register_operand" "w")]
2124 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2125 [(set (attr "neon_type")
2126 (if_then_else (match_test "<Is_float_mode>")
2127 (if_then_else (match_test "<Is_d_reg>")
2128 (const_string "neon_fp_vmla_ddd")
2129 (const_string "neon_fp_vmla_qqq"))
2130 (if_then_else (match_test "<Is_d_reg>")
2132 (match_test "<Scalar_mul_8_16>")
2133 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2134 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
2135 (if_then_else (match_test "<Scalar_mul_8_16>")
2136 (const_string "neon_mla_qqq_8_16")
2137 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
2140 (define_insn "neon_vmlal<mode>"
2141 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2142 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2143 (match_operand:VW 2 "s_register_operand" "w")
2144 (match_operand:VW 3 "s_register_operand" "w")
2145 (match_operand:SI 4 "immediate_operand" "i")]
2148 "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2149 [(set (attr "neon_type")
2150 (if_then_else (match_test "<Scalar_mul_8_16>")
2151 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2152 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2155 (define_expand "neon_vmls<mode>"
2156 [(match_operand:VDQW 0 "s_register_operand" "=w")
2157 (match_operand:VDQW 1 "s_register_operand" "0")
2158 (match_operand:VDQW 2 "s_register_operand" "w")
2159 (match_operand:VDQW 3 "s_register_operand" "w")
2160 (match_operand:SI 4 "immediate_operand" "i")]
2163 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2164 emit_insn (gen_mul<mode>3neg<mode>add<mode>_neon (operands[0],
2165 operands[1], operands[2], operands[3]));
2167 emit_insn (gen_neon_vmls<mode>_unspec (operands[0], operands[1],
2168 operands[2], operands[3]));
2172 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2174 (define_insn "neon_vmls<mode>_unspec"
2175 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
2176 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
2177 (match_operand:VDQ 2 "s_register_operand" "w")
2178 (match_operand:VDQ 3 "s_register_operand" "w")]
2181 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2182 [(set (attr "neon_type")
2183 (if_then_else (match_test "<Is_float_mode>")
2184 (if_then_else (match_test "<Is_d_reg>")
2185 (const_string "neon_fp_vmla_ddd")
2186 (const_string "neon_fp_vmla_qqq"))
2187 (if_then_else (match_test "<Is_d_reg>")
2189 (match_test "<Scalar_mul_8_16>")
2190 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2191 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
2193 (match_test "<Scalar_mul_8_16>")
2194 (const_string "neon_mla_qqq_8_16")
2195 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
2198 (define_insn "neon_vmlsl<mode>"
2199 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2200 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2201 (match_operand:VW 2 "s_register_operand" "w")
2202 (match_operand:VW 3 "s_register_operand" "w")
2203 (match_operand:SI 4 "immediate_operand" "i")]
2206 "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2207 [(set (attr "neon_type")
2208 (if_then_else (match_test "<Scalar_mul_8_16>")
2209 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2210 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2213 (define_insn "neon_vqdmulh<mode>"
2214 [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
2215 (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
2216 (match_operand:VMDQI 2 "s_register_operand" "w")
2217 (match_operand:SI 3 "immediate_operand" "i")]
2220 "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2221 [(set (attr "neon_type")
2222 (if_then_else (match_test "<Is_d_reg>")
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_qqq_8_16_32_ddd_32"))
2226 (if_then_else (match_test "<Scalar_mul_8_16>")
2227 (const_string "neon_mul_qqq_8_16_32_ddd_32")
2228 (const_string "neon_mul_qqq_8_16_32_ddd_32"))))]
2231 (define_insn "neon_vqdmlal<mode>"
2232 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2233 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2234 (match_operand:VMDI 2 "s_register_operand" "w")
2235 (match_operand:VMDI 3 "s_register_operand" "w")
2236 (match_operand:SI 4 "immediate_operand" "i")]
2239 "vqdmlal.<V_s_elem>\t%q0, %P2, %P3"
2240 [(set (attr "neon_type")
2241 (if_then_else (match_test "<Scalar_mul_8_16>")
2242 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2243 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2246 (define_insn "neon_vqdmlsl<mode>"
2247 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2248 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2249 (match_operand:VMDI 2 "s_register_operand" "w")
2250 (match_operand:VMDI 3 "s_register_operand" "w")
2251 (match_operand:SI 4 "immediate_operand" "i")]
2254 "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3"
2255 [(set (attr "neon_type")
2256 (if_then_else (match_test "<Scalar_mul_8_16>")
2257 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2258 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2261 (define_insn "neon_vmull<mode>"
2262 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2263 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2264 (match_operand:VW 2 "s_register_operand" "w")
2265 (match_operand:SI 3 "immediate_operand" "i")]
2268 "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2269 [(set (attr "neon_type")
2270 (if_then_else (match_test "<Scalar_mul_8_16>")
2271 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2272 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2275 (define_insn "neon_vqdmull<mode>"
2276 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2277 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
2278 (match_operand:VMDI 2 "s_register_operand" "w")
2279 (match_operand:SI 3 "immediate_operand" "i")]
2282 "vqdmull.<V_s_elem>\t%q0, %P1, %P2"
2283 [(set (attr "neon_type")
2284 (if_then_else (match_test "<Scalar_mul_8_16>")
2285 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2286 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2289 (define_expand "neon_vsub<mode>"
2290 [(match_operand:VDQX 0 "s_register_operand" "=w")
2291 (match_operand:VDQX 1 "s_register_operand" "w")
2292 (match_operand:VDQX 2 "s_register_operand" "w")
2293 (match_operand:SI 3 "immediate_operand" "i")]
2296 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2297 emit_insn (gen_sub<mode>3 (operands[0], operands[1], operands[2]));
2299 emit_insn (gen_neon_vsub<mode>_unspec (operands[0], operands[1],
2304 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2306 (define_insn "neon_vsub<mode>_unspec"
2307 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
2308 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
2309 (match_operand:VDQX 2 "s_register_operand" "w")]
2312 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2313 [(set (attr "neon_type")
2314 (if_then_else (match_test "<Is_float_mode>")
2315 (if_then_else (match_test "<Is_d_reg>")
2316 (const_string "neon_fp_vadd_ddd_vabs_dd")
2317 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2318 (const_string "neon_int_2")))]
2321 (define_insn "neon_vsubl<mode>"
2322 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2323 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
2324 (match_operand:VDI 2 "s_register_operand" "w")
2325 (match_operand:SI 3 "immediate_operand" "i")]
2328 "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2329 [(set_attr "neon_type" "neon_int_2")]
2332 (define_insn "neon_vsubw<mode>"
2333 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2334 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
2335 (match_operand:VDI 2 "s_register_operand" "w")
2336 (match_operand:SI 3 "immediate_operand" "i")]
2339 "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
2340 [(set_attr "neon_type" "neon_int_2")]
2343 (define_insn "neon_vqsub<mode>"
2344 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2345 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2346 (match_operand:VDQIX 2 "s_register_operand" "w")
2347 (match_operand:SI 3 "immediate_operand" "i")]
2350 "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2351 [(set_attr "neon_type" "neon_int_5")]
2354 (define_insn "neon_vhsub<mode>"
2355 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2356 (unspec:VDQIW [(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 "vhsub.%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_vsubhn<mode>"
2366 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2367 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2368 (match_operand:VN 2 "s_register_operand" "w")
2369 (match_operand:SI 3 "immediate_operand" "i")]
2372 "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2"
2373 [(set_attr "neon_type" "neon_int_4")]
2376 (define_insn "neon_vceq<mode>"
2377 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2378 (unspec:<V_cmp_result>
2379 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2380 (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2381 (match_operand:SI 3 "immediate_operand" "i,i")]
2385 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2386 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, #0"
2387 [(set (attr "neon_type")
2388 (if_then_else (match_test "<Is_float_mode>")
2389 (if_then_else (match_test "<Is_d_reg>")
2390 (const_string "neon_fp_vadd_ddd_vabs_dd")
2391 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2392 (const_string "neon_int_5")))]
2395 (define_insn "neon_vcge<mode>"
2396 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2397 (unspec:<V_cmp_result>
2398 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2399 (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2400 (match_operand:SI 3 "immediate_operand" "i,i")]
2404 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2405 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2406 [(set (attr "neon_type")
2407 (if_then_else (match_test "<Is_float_mode>")
2408 (if_then_else (match_test "<Is_d_reg>")
2409 (const_string "neon_fp_vadd_ddd_vabs_dd")
2410 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2411 (const_string "neon_int_5")))]
2414 (define_insn "neon_vcgeu<mode>"
2415 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2416 (unspec:<V_cmp_result>
2417 [(match_operand:VDQIW 1 "s_register_operand" "w")
2418 (match_operand:VDQIW 2 "s_register_operand" "w")
2419 (match_operand:SI 3 "immediate_operand" "i")]
2422 "vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2423 [(set_attr "neon_type" "neon_int_5")]
2426 (define_insn "neon_vcgt<mode>"
2427 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2428 (unspec:<V_cmp_result>
2429 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2430 (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2431 (match_operand:SI 3 "immediate_operand" "i,i")]
2435 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2436 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2437 [(set (attr "neon_type")
2438 (if_then_else (match_test "<Is_float_mode>")
2439 (if_then_else (match_test "<Is_d_reg>")
2440 (const_string "neon_fp_vadd_ddd_vabs_dd")
2441 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2442 (const_string "neon_int_5")))]
2445 (define_insn "neon_vcgtu<mode>"
2446 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2447 (unspec:<V_cmp_result>
2448 [(match_operand:VDQIW 1 "s_register_operand" "w")
2449 (match_operand:VDQIW 2 "s_register_operand" "w")
2450 (match_operand:SI 3 "immediate_operand" "i")]
2453 "vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2454 [(set_attr "neon_type" "neon_int_5")]
2457 ;; VCLE and VCLT only support comparisons with immediate zero (register
2458 ;; variants are VCGE and VCGT with operands reversed).
2460 (define_insn "neon_vcle<mode>"
2461 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2462 (unspec:<V_cmp_result>
2463 [(match_operand:VDQW 1 "s_register_operand" "w")
2464 (match_operand:VDQW 2 "zero_operand" "Dz")
2465 (match_operand:SI 3 "immediate_operand" "i")]
2468 "vcle.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2469 [(set (attr "neon_type")
2470 (if_then_else (match_test "<Is_float_mode>")
2471 (if_then_else (match_test "<Is_d_reg>")
2472 (const_string "neon_fp_vadd_ddd_vabs_dd")
2473 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2474 (const_string "neon_int_5")))]
2477 (define_insn "neon_vclt<mode>"
2478 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2479 (unspec:<V_cmp_result>
2480 [(match_operand:VDQW 1 "s_register_operand" "w")
2481 (match_operand:VDQW 2 "zero_operand" "Dz")
2482 (match_operand:SI 3 "immediate_operand" "i")]
2485 "vclt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2486 [(set (attr "neon_type")
2487 (if_then_else (match_test "<Is_float_mode>")
2488 (if_then_else (match_test "<Is_d_reg>")
2489 (const_string "neon_fp_vadd_ddd_vabs_dd")
2490 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2491 (const_string "neon_int_5")))]
2494 (define_insn "neon_vcage<mode>"
2495 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2496 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2497 (match_operand:VCVTF 2 "s_register_operand" "w")
2498 (match_operand:SI 3 "immediate_operand" "i")]
2501 "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2502 [(set (attr "neon_type")
2503 (if_then_else (match_test "<Is_d_reg>")
2504 (const_string "neon_fp_vadd_ddd_vabs_dd")
2505 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2508 (define_insn "neon_vcagt<mode>"
2509 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2510 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2511 (match_operand:VCVTF 2 "s_register_operand" "w")
2512 (match_operand:SI 3 "immediate_operand" "i")]
2515 "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2516 [(set (attr "neon_type")
2517 (if_then_else (match_test "<Is_d_reg>")
2518 (const_string "neon_fp_vadd_ddd_vabs_dd")
2519 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2522 (define_insn "neon_vtst<mode>"
2523 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2524 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2525 (match_operand:VDQIW 2 "s_register_operand" "w")
2526 (match_operand:SI 3 "immediate_operand" "i")]
2529 "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2530 [(set_attr "neon_type" "neon_int_4")]
2533 (define_insn "neon_vabd<mode>"
2534 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2535 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2536 (match_operand:VDQW 2 "s_register_operand" "w")
2537 (match_operand:SI 3 "immediate_operand" "i")]
2540 "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2541 [(set (attr "neon_type")
2542 (if_then_else (match_test "<Is_float_mode>")
2543 (if_then_else (match_test "<Is_d_reg>")
2544 (const_string "neon_fp_vadd_ddd_vabs_dd")
2545 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2546 (const_string "neon_int_5")))]
2549 (define_insn "neon_vabdl<mode>"
2550 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2551 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2552 (match_operand:VW 2 "s_register_operand" "w")
2553 (match_operand:SI 3 "immediate_operand" "i")]
2556 "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2557 [(set_attr "neon_type" "neon_int_5")]
2560 (define_insn "neon_vaba<mode>"
2561 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2562 (plus:VDQIW (unspec:VDQIW [(match_operand:VDQIW 2 "s_register_operand" "w")
2563 (match_operand:VDQIW 3 "s_register_operand" "w")
2564 (match_operand:SI 4 "immediate_operand" "i")]
2566 (match_operand:VDQIW 1 "s_register_operand" "0")))]
2568 "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2569 [(set (attr "neon_type")
2570 (if_then_else (match_test "<Is_d_reg>")
2571 (const_string "neon_vaba") (const_string "neon_vaba_qqq")))]
2574 (define_insn "neon_vabal<mode>"
2575 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2576 (plus:<V_widen> (unspec:<V_widen> [(match_operand:VW 2 "s_register_operand" "w")
2577 (match_operand:VW 3 "s_register_operand" "w")
2578 (match_operand:SI 4 "immediate_operand" "i")]
2580 (match_operand:<V_widen> 1 "s_register_operand" "0")))]
2582 "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2583 [(set_attr "neon_type" "neon_vaba")]
2586 (define_insn "neon_vmax<mode>"
2587 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2588 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2589 (match_operand:VDQW 2 "s_register_operand" "w")
2590 (match_operand:SI 3 "immediate_operand" "i")]
2593 "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2594 [(set (attr "neon_type")
2595 (if_then_else (match_test "<Is_float_mode>")
2596 (if_then_else (match_test "<Is_d_reg>")
2597 (const_string "neon_fp_vadd_ddd_vabs_dd")
2598 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2599 (const_string "neon_int_5")))]
2602 (define_insn "neon_vmin<mode>"
2603 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2604 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2605 (match_operand:VDQW 2 "s_register_operand" "w")
2606 (match_operand:SI 3 "immediate_operand" "i")]
2609 "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2610 [(set (attr "neon_type")
2611 (if_then_else (match_test "<Is_float_mode>")
2612 (if_then_else (match_test "<Is_d_reg>")
2613 (const_string "neon_fp_vadd_ddd_vabs_dd")
2614 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2615 (const_string "neon_int_5")))]
2618 (define_expand "neon_vpadd<mode>"
2619 [(match_operand:VD 0 "s_register_operand" "=w")
2620 (match_operand:VD 1 "s_register_operand" "w")
2621 (match_operand:VD 2 "s_register_operand" "w")
2622 (match_operand:SI 3 "immediate_operand" "i")]
2625 emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1],
2630 (define_insn "neon_vpaddl<mode>"
2631 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2632 (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")
2633 (match_operand:SI 2 "immediate_operand" "i")]
2636 "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2637 ;; Assume this schedules like vaddl.
2638 [(set_attr "neon_type" "neon_int_3")]
2641 (define_insn "neon_vpadal<mode>"
2642 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2643 (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0")
2644 (match_operand:VDQIW 2 "s_register_operand" "w")
2645 (match_operand:SI 3 "immediate_operand" "i")]
2648 "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
2649 ;; Assume this schedules like vpadd.
2650 [(set_attr "neon_type" "neon_int_1")]
2653 (define_insn "neon_vpmax<mode>"
2654 [(set (match_operand:VD 0 "s_register_operand" "=w")
2655 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2656 (match_operand:VD 2 "s_register_operand" "w")
2657 (match_operand:SI 3 "immediate_operand" "i")]
2660 "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2661 ;; Assume this schedules like vmax.
2662 [(set (attr "neon_type")
2663 (if_then_else (match_test "<Is_float_mode>")
2664 (const_string "neon_fp_vadd_ddd_vabs_dd")
2665 (const_string "neon_int_5")))]
2668 (define_insn "neon_vpmin<mode>"
2669 [(set (match_operand:VD 0 "s_register_operand" "=w")
2670 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2671 (match_operand:VD 2 "s_register_operand" "w")
2672 (match_operand:SI 3 "immediate_operand" "i")]
2675 "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2676 ;; Assume this schedules like vmin.
2677 [(set (attr "neon_type")
2678 (if_then_else (match_test "<Is_float_mode>")
2679 (const_string "neon_fp_vadd_ddd_vabs_dd")
2680 (const_string "neon_int_5")))]
2683 (define_insn "neon_vrecps<mode>"
2684 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2685 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2686 (match_operand:VCVTF 2 "s_register_operand" "w")
2687 (match_operand:SI 3 "immediate_operand" "i")]
2690 "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2691 [(set (attr "neon_type")
2692 (if_then_else (match_test "<Is_d_reg>")
2693 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2694 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2697 (define_insn "neon_vrsqrts<mode>"
2698 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2699 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2700 (match_operand:VCVTF 2 "s_register_operand" "w")
2701 (match_operand:SI 3 "immediate_operand" "i")]
2704 "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2705 [(set (attr "neon_type")
2706 (if_then_else (match_test "<Is_d_reg>")
2707 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2708 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2711 (define_expand "neon_vabs<mode>"
2712 [(match_operand:VDQW 0 "s_register_operand" "")
2713 (match_operand:VDQW 1 "s_register_operand" "")
2714 (match_operand:SI 2 "immediate_operand" "")]
2717 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
2721 (define_insn "neon_vqabs<mode>"
2722 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2723 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2724 (match_operand:SI 2 "immediate_operand" "i")]
2727 "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2728 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2731 (define_expand "neon_vneg<mode>"
2732 [(match_operand:VDQW 0 "s_register_operand" "")
2733 (match_operand:VDQW 1 "s_register_operand" "")
2734 (match_operand:SI 2 "immediate_operand" "")]
2737 emit_insn (gen_neg<mode>2 (operands[0], operands[1]));
2741 (define_insn "neon_vqneg<mode>"
2742 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2743 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2744 (match_operand:SI 2 "immediate_operand" "i")]
2747 "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2748 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2751 (define_insn "neon_vcls<mode>"
2752 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2753 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2754 (match_operand:SI 2 "immediate_operand" "i")]
2757 "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2758 [(set_attr "neon_type" "neon_int_1")]
2761 (define_insn "clz<mode>2"
2762 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2763 (clz:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")))]
2765 "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1"
2766 [(set_attr "neon_type" "neon_int_1")]
2769 (define_expand "neon_vclz<mode>"
2770 [(match_operand:VDQIW 0 "s_register_operand" "")
2771 (match_operand:VDQIW 1 "s_register_operand" "")
2772 (match_operand:SI 2 "immediate_operand" "")]
2775 emit_insn (gen_clz<mode>2 (operands[0], operands[1]));
2779 (define_insn "popcount<mode>2"
2780 [(set (match_operand:VE 0 "s_register_operand" "=w")
2781 (popcount:VE (match_operand:VE 1 "s_register_operand" "w")))]
2783 "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2784 [(set_attr "neon_type" "neon_int_1")]
2787 (define_expand "neon_vcnt<mode>"
2788 [(match_operand:VE 0 "s_register_operand" "=w")
2789 (match_operand:VE 1 "s_register_operand" "w")
2790 (match_operand:SI 2 "immediate_operand" "i")]
2793 emit_insn (gen_popcount<mode>2 (operands[0], operands[1]));
2797 (define_insn "neon_vrecpe<mode>"
2798 [(set (match_operand:V32 0 "s_register_operand" "=w")
2799 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2800 (match_operand:SI 2 "immediate_operand" "i")]
2803 "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2804 [(set (attr "neon_type")
2805 (if_then_else (match_test "<Is_d_reg>")
2806 (const_string "neon_fp_vadd_ddd_vabs_dd")
2807 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2810 (define_insn "neon_vrsqrte<mode>"
2811 [(set (match_operand:V32 0 "s_register_operand" "=w")
2812 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2813 (match_operand:SI 2 "immediate_operand" "i")]
2816 "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2817 [(set (attr "neon_type")
2818 (if_then_else (match_test "<Is_d_reg>")
2819 (const_string "neon_fp_vadd_ddd_vabs_dd")
2820 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2823 (define_expand "neon_vmvn<mode>"
2824 [(match_operand:VDQIW 0 "s_register_operand" "")
2825 (match_operand:VDQIW 1 "s_register_operand" "")
2826 (match_operand:SI 2 "immediate_operand" "")]
2829 emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1]));
2833 (define_insn "neon_vget_lane<mode>_sext_internal"
2834 [(set (match_operand:SI 0 "s_register_operand" "=r")
2836 (vec_select:<V_elem>
2837 (match_operand:VD 1 "s_register_operand" "w")
2838 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2841 if (BYTES_BIG_ENDIAN)
2843 int elt = INTVAL (operands[2]);
2844 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2845 operands[2] = GEN_INT (elt);
2847 return "vmov.s<V_sz_elem>\t%0, %P1[%c2]";
2849 [(set_attr "neon_type" "neon_bp_simple")]
2852 (define_insn "neon_vget_lane<mode>_zext_internal"
2853 [(set (match_operand:SI 0 "s_register_operand" "=r")
2855 (vec_select:<V_elem>
2856 (match_operand:VD 1 "s_register_operand" "w")
2857 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2860 if (BYTES_BIG_ENDIAN)
2862 int elt = INTVAL (operands[2]);
2863 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2864 operands[2] = GEN_INT (elt);
2866 return "vmov.u<V_sz_elem>\t%0, %P1[%c2]";
2868 [(set_attr "neon_type" "neon_bp_simple")]
2871 (define_insn "neon_vget_lane<mode>_sext_internal"
2872 [(set (match_operand:SI 0 "s_register_operand" "=r")
2874 (vec_select:<V_elem>
2875 (match_operand:VQ 1 "s_register_operand" "w")
2876 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2880 int regno = REGNO (operands[1]);
2881 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2882 unsigned int elt = INTVAL (operands[2]);
2883 unsigned int elt_adj = elt % halfelts;
2885 if (BYTES_BIG_ENDIAN)
2886 elt_adj = halfelts - 1 - elt_adj;
2888 ops[0] = operands[0];
2889 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2890 ops[2] = GEN_INT (elt_adj);
2891 output_asm_insn ("vmov.s<V_sz_elem>\t%0, %P1[%c2]", ops);
2895 [(set_attr "neon_type" "neon_bp_simple")]
2898 (define_insn "neon_vget_lane<mode>_zext_internal"
2899 [(set (match_operand:SI 0 "s_register_operand" "=r")
2901 (vec_select:<V_elem>
2902 (match_operand:VQ 1 "s_register_operand" "w")
2903 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2907 int regno = REGNO (operands[1]);
2908 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2909 unsigned int elt = INTVAL (operands[2]);
2910 unsigned int elt_adj = elt % halfelts;
2912 if (BYTES_BIG_ENDIAN)
2913 elt_adj = halfelts - 1 - elt_adj;
2915 ops[0] = operands[0];
2916 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2917 ops[2] = GEN_INT (elt_adj);
2918 output_asm_insn ("vmov.u<V_sz_elem>\t%0, %P1[%c2]", ops);
2922 [(set_attr "neon_type" "neon_bp_simple")]
2925 (define_expand "neon_vget_lane<mode>"
2926 [(match_operand:<V_ext> 0 "s_register_operand" "")
2927 (match_operand:VDQW 1 "s_register_operand" "")
2928 (match_operand:SI 2 "immediate_operand" "")
2929 (match_operand:SI 3 "immediate_operand" "")]
2932 HOST_WIDE_INT magic = INTVAL (operands[3]);
2935 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode));
2937 if (BYTES_BIG_ENDIAN)
2939 /* The intrinsics are defined in terms of a model where the
2940 element ordering in memory is vldm order, whereas the generic
2941 RTL is defined in terms of a model where the element ordering
2942 in memory is array order. Convert the lane number to conform
2944 unsigned int elt = INTVAL (operands[2]);
2945 unsigned int reg_nelts
2946 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2947 elt ^= reg_nelts - 1;
2948 operands[2] = GEN_INT (elt);
2951 if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32)
2952 insn = gen_vec_extract<mode> (operands[0], operands[1], operands[2]);
2955 if ((magic & 1) != 0)
2956 insn = gen_neon_vget_lane<mode>_sext_internal (operands[0], operands[1],
2959 insn = gen_neon_vget_lane<mode>_zext_internal (operands[0], operands[1],
2966 ; Operand 3 (info word) is ignored because it does nothing useful with 64-bit
2969 (define_expand "neon_vget_lanedi"
2970 [(match_operand:DI 0 "s_register_operand" "=r")
2971 (match_operand:DI 1 "s_register_operand" "w")
2972 (match_operand:SI 2 "immediate_operand" "i")
2973 (match_operand:SI 3 "immediate_operand" "i")]
2976 neon_lane_bounds (operands[2], 0, 1);
2977 emit_move_insn (operands[0], operands[1]);
2981 (define_expand "neon_vget_lanev2di"
2982 [(match_operand:DI 0 "s_register_operand" "")
2983 (match_operand:V2DI 1 "s_register_operand" "")
2984 (match_operand:SI 2 "immediate_operand" "")
2985 (match_operand:SI 3 "immediate_operand" "")]
2988 switch (INTVAL (operands[2]))
2991 emit_move_insn (operands[0], gen_lowpart (DImode, operands[1]));
2994 emit_move_insn (operands[0], gen_highpart (DImode, operands[1]));
2997 neon_lane_bounds (operands[2], 0, 1);
3003 (define_expand "neon_vset_lane<mode>"
3004 [(match_operand:VDQ 0 "s_register_operand" "=w")
3005 (match_operand:<V_elem> 1 "s_register_operand" "r")
3006 (match_operand:VDQ 2 "s_register_operand" "0")
3007 (match_operand:SI 3 "immediate_operand" "i")]
3010 unsigned int elt = INTVAL (operands[3]);
3011 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3013 if (BYTES_BIG_ENDIAN)
3015 unsigned int reg_nelts
3016 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
3017 elt ^= reg_nelts - 1;
3020 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
3021 GEN_INT (1 << elt), operands[2]));
3025 ; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
3027 (define_expand "neon_vset_lanedi"
3028 [(match_operand:DI 0 "s_register_operand" "=w")
3029 (match_operand:DI 1 "s_register_operand" "r")
3030 (match_operand:DI 2 "s_register_operand" "0")
3031 (match_operand:SI 3 "immediate_operand" "i")]
3034 neon_lane_bounds (operands[3], 0, 1);
3035 emit_move_insn (operands[0], operands[1]);
3039 (define_expand "neon_vcreate<mode>"
3040 [(match_operand:VDX 0 "s_register_operand" "")
3041 (match_operand:DI 1 "general_operand" "")]
3044 rtx src = gen_lowpart (<MODE>mode, operands[1]);
3045 emit_move_insn (operands[0], src);
3049 (define_insn "neon_vdup_n<mode>"
3050 [(set (match_operand:VX 0 "s_register_operand" "=w")
3051 (vec_duplicate:VX (match_operand:<V_elem> 1 "s_register_operand" "r")))]
3053 "vdup.<V_sz_elem>\t%<V_reg>0, %1"
3054 ;; Assume this schedules like vmov.
3055 [(set_attr "neon_type" "neon_bp_simple")]
3058 (define_insn "neon_vdup_n<mode>"
3059 [(set (match_operand:V32 0 "s_register_operand" "=w,w")
3060 (vec_duplicate:V32 (match_operand:<V_elem> 1 "s_register_operand" "r,t")))]
3063 vdup.<V_sz_elem>\t%<V_reg>0, %1
3064 vdup.<V_sz_elem>\t%<V_reg>0, %y1"
3065 ;; Assume this schedules like vmov.
3066 [(set_attr "neon_type" "neon_bp_simple")]
3069 (define_expand "neon_vdup_ndi"
3070 [(match_operand:DI 0 "s_register_operand" "=w")
3071 (match_operand:DI 1 "s_register_operand" "r")]
3074 emit_move_insn (operands[0], operands[1]);
3079 (define_insn "neon_vdup_nv2di"
3080 [(set (match_operand:V2DI 0 "s_register_operand" "=w,w")
3081 (vec_duplicate:V2DI (match_operand:DI 1 "s_register_operand" "r,w")))]
3084 vmov\t%e0, %Q1, %R1\;vmov\t%f0, %Q1, %R1
3085 vmov\t%e0, %P1\;vmov\t%f0, %P1"
3086 [(set_attr "length" "8")
3087 (set_attr "neon_type" "neon_bp_simple")]
3090 (define_insn "neon_vdup_lane<mode>_internal"
3091 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3093 (vec_select:<V_elem>
3094 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
3095 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
3098 if (BYTES_BIG_ENDIAN)
3100 int elt = INTVAL (operands[2]);
3101 elt = GET_MODE_NUNITS (<V_double_vector_mode>mode) - 1 - elt;
3102 operands[2] = GEN_INT (elt);
3105 return "vdup.<V_sz_elem>\t%P0, %P1[%c2]";
3107 return "vdup.<V_sz_elem>\t%q0, %P1[%c2]";
3109 ;; Assume this schedules like vmov.
3110 [(set_attr "neon_type" "neon_bp_simple")]
3113 (define_expand "neon_vdup_lane<mode>"
3114 [(match_operand:VDQW 0 "s_register_operand" "=w")
3115 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
3116 (match_operand:SI 2 "immediate_operand" "i")]
3119 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<V_double_vector_mode>mode));
3120 if (BYTES_BIG_ENDIAN)
3122 unsigned int elt = INTVAL (operands[2]);
3123 unsigned int reg_nelts
3124 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<V_double_vector_mode>mode));
3125 elt ^= reg_nelts - 1;
3126 operands[2] = GEN_INT (elt);
3128 emit_insn (gen_neon_vdup_lane<mode>_internal (operands[0], operands[1],
3133 ; Scalar index is ignored, since only zero is valid here.
3134 (define_expand "neon_vdup_lanedi"
3135 [(match_operand:DI 0 "s_register_operand" "=w")
3136 (match_operand:DI 1 "s_register_operand" "w")
3137 (match_operand:SI 2 "immediate_operand" "i")]
3140 neon_lane_bounds (operands[2], 0, 1);
3141 emit_move_insn (operands[0], operands[1]);
3145 ; Likewise for v2di, as the DImode second operand has only a single element.
3146 (define_expand "neon_vdup_lanev2di"
3147 [(match_operand:V2DI 0 "s_register_operand" "=w")
3148 (match_operand:DI 1 "s_register_operand" "w")
3149 (match_operand:SI 2 "immediate_operand" "i")]
3152 neon_lane_bounds (operands[2], 0, 1);
3153 emit_insn (gen_neon_vdup_nv2di (operands[0], operands[1]));
3157 ; Disabled before reload because we don't want combine doing something silly,
3158 ; but used by the post-reload expansion of neon_vcombine.
3159 (define_insn "*neon_vswp<mode>"
3160 [(set (match_operand:VDQX 0 "s_register_operand" "+w")
3161 (match_operand:VDQX 1 "s_register_operand" "+w"))
3162 (set (match_dup 1) (match_dup 0))]
3163 "TARGET_NEON && reload_completed"
3164 "vswp\t%<V_reg>0, %<V_reg>1"
3165 [(set (attr "neon_type")
3166 (if_then_else (match_test "<Is_d_reg>")
3167 (const_string "neon_bp_simple")
3168 (const_string "neon_bp_2cycle")))]
3171 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
3173 ;; FIXME: A different implementation of this builtin could make it much
3174 ;; more likely that we wouldn't actually need to output anything (we could make
3175 ;; it so that the reg allocator puts things in the right places magically
3176 ;; instead). Lack of subregs for vectors makes that tricky though, I think.
3178 (define_insn_and_split "neon_vcombine<mode>"
3179 [(set (match_operand:<V_DOUBLE> 0 "s_register_operand" "=w")
3180 (vec_concat:<V_DOUBLE>
3181 (match_operand:VDX 1 "s_register_operand" "w")
3182 (match_operand:VDX 2 "s_register_operand" "w")))]
3185 "&& reload_completed"
3188 neon_split_vcombine (operands);
3192 (define_expand "neon_vget_high<mode>"
3193 [(match_operand:<V_HALF> 0 "s_register_operand")
3194 (match_operand:VQX 1 "s_register_operand")]
3197 emit_move_insn (operands[0],
3198 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode,
3199 GET_MODE_SIZE (<V_HALF>mode)));
3203 (define_expand "neon_vget_low<mode>"
3204 [(match_operand:<V_HALF> 0 "s_register_operand")
3205 (match_operand:VQX 1 "s_register_operand")]
3208 emit_move_insn (operands[0],
3209 simplify_gen_subreg (<V_HALF>mode, operands[1],
3214 (define_insn "float<mode><V_cvtto>2"
3215 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3216 (float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))]
3217 "TARGET_NEON && !flag_rounding_math"
3218 "vcvt.f32.s32\t%<V_reg>0, %<V_reg>1"
3219 [(set (attr "neon_type")
3220 (if_then_else (match_test "<Is_d_reg>")
3221 (const_string "neon_fp_vadd_ddd_vabs_dd")
3222 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3225 (define_insn "floatuns<mode><V_cvtto>2"
3226 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3227 (unsigned_float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))]
3228 "TARGET_NEON && !flag_rounding_math"
3229 "vcvt.f32.u32\t%<V_reg>0, %<V_reg>1"
3230 [(set (attr "neon_type")
3231 (if_then_else (match_test "<Is_d_reg>")
3232 (const_string "neon_fp_vadd_ddd_vabs_dd")
3233 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3236 (define_insn "fix_trunc<mode><V_cvtto>2"
3237 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3238 (fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))]
3240 "vcvt.s32.f32\t%<V_reg>0, %<V_reg>1"
3241 [(set (attr "neon_type")
3242 (if_then_else (match_test "<Is_d_reg>")
3243 (const_string "neon_fp_vadd_ddd_vabs_dd")
3244 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3247 (define_insn "fixuns_trunc<mode><V_cvtto>2"
3248 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3249 (unsigned_fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))]
3251 "vcvt.u32.f32\t%<V_reg>0, %<V_reg>1"
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<mode>"
3259 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3260 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3261 (match_operand:SI 2 "immediate_operand" "i")]
3264 "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1"
3265 [(set (attr "neon_type")
3266 (if_then_else (match_test "<Is_d_reg>")
3267 (const_string "neon_fp_vadd_ddd_vabs_dd")
3268 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3271 (define_insn "neon_vcvt<mode>"
3272 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3273 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3274 (match_operand:SI 2 "immediate_operand" "i")]
3277 "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1"
3278 [(set (attr "neon_type")
3279 (if_then_else (match_test "<Is_d_reg>")
3280 (const_string "neon_fp_vadd_ddd_vabs_dd")
3281 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3284 (define_insn "neon_vcvt_n<mode>"
3285 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3286 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3287 (match_operand:SI 2 "immediate_operand" "i")
3288 (match_operand:SI 3 "immediate_operand" "i")]
3292 neon_const_bounds (operands[2], 1, 33);
3293 return "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2";
3295 [(set (attr "neon_type")
3296 (if_then_else (match_test "<Is_d_reg>")
3297 (const_string "neon_fp_vadd_ddd_vabs_dd")
3298 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3301 (define_insn "neon_vcvt_n<mode>"
3302 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3303 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3304 (match_operand:SI 2 "immediate_operand" "i")
3305 (match_operand:SI 3 "immediate_operand" "i")]
3309 neon_const_bounds (operands[2], 1, 33);
3310 return "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2";
3312 [(set (attr "neon_type")
3313 (if_then_else (match_test "<Is_d_reg>")
3314 (const_string "neon_fp_vadd_ddd_vabs_dd")
3315 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3318 (define_insn "neon_vmovn<mode>"
3319 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3320 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3321 (match_operand:SI 2 "immediate_operand" "i")]
3324 "vmovn.<V_if_elem>\t%P0, %q1"
3325 [(set_attr "neon_type" "neon_bp_simple")]
3328 (define_insn "neon_vqmovn<mode>"
3329 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3330 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3331 (match_operand:SI 2 "immediate_operand" "i")]
3334 "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1"
3335 [(set_attr "neon_type" "neon_shift_2")]
3338 (define_insn "neon_vqmovun<mode>"
3339 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3340 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3341 (match_operand:SI 2 "immediate_operand" "i")]
3344 "vqmovun.<V_s_elem>\t%P0, %q1"
3345 [(set_attr "neon_type" "neon_shift_2")]
3348 (define_insn "neon_vmovl<mode>"
3349 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3350 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
3351 (match_operand:SI 2 "immediate_operand" "i")]
3354 "vmovl.%T2%#<V_sz_elem>\t%q0, %P1"
3355 [(set_attr "neon_type" "neon_shift_1")]
3358 (define_insn "neon_vmul_lane<mode>"
3359 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3360 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
3361 (match_operand:VMD 2 "s_register_operand"
3362 "<scalar_mul_constraint>")
3363 (match_operand:SI 3 "immediate_operand" "i")
3364 (match_operand:SI 4 "immediate_operand" "i")]
3368 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3369 return "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]";
3371 [(set (attr "neon_type")
3372 (if_then_else (match_test "<Is_float_mode>")
3373 (const_string "neon_fp_vmul_ddd")
3374 (if_then_else (match_test "<Scalar_mul_8_16>")
3375 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3376 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))))]
3379 (define_insn "neon_vmul_lane<mode>"
3380 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3381 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
3382 (match_operand:<V_HALF> 2 "s_register_operand"
3383 "<scalar_mul_constraint>")
3384 (match_operand:SI 3 "immediate_operand" "i")
3385 (match_operand:SI 4 "immediate_operand" "i")]
3389 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<V_HALF>mode));
3390 return "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]";
3392 [(set (attr "neon_type")
3393 (if_then_else (match_test "<Is_float_mode>")
3394 (const_string "neon_fp_vmul_qqd")
3395 (if_then_else (match_test "<Scalar_mul_8_16>")
3396 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3397 (const_string "neon_mul_qqd_32_scalar"))))]
3400 (define_insn "neon_vmull_lane<mode>"
3401 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3402 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3403 (match_operand:VMDI 2 "s_register_operand"
3404 "<scalar_mul_constraint>")
3405 (match_operand:SI 3 "immediate_operand" "i")
3406 (match_operand:SI 4 "immediate_operand" "i")]
3407 UNSPEC_VMULL_LANE))]
3410 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3411 return "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]";
3413 [(set (attr "neon_type")
3414 (if_then_else (match_test "<Scalar_mul_8_16>")
3415 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3416 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3419 (define_insn "neon_vqdmull_lane<mode>"
3420 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3421 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3422 (match_operand:VMDI 2 "s_register_operand"
3423 "<scalar_mul_constraint>")
3424 (match_operand:SI 3 "immediate_operand" "i")
3425 (match_operand:SI 4 "immediate_operand" "i")]
3426 UNSPEC_VQDMULL_LANE))]
3429 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3430 return "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]";
3432 [(set (attr "neon_type")
3433 (if_then_else (match_test "<Scalar_mul_8_16>")
3434 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3435 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3438 (define_insn "neon_vqdmulh_lane<mode>"
3439 [(set (match_operand:VMQI 0 "s_register_operand" "=w")
3440 (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
3441 (match_operand:<V_HALF> 2 "s_register_operand"
3442 "<scalar_mul_constraint>")
3443 (match_operand:SI 3 "immediate_operand" "i")
3444 (match_operand:SI 4 "immediate_operand" "i")]
3445 UNSPEC_VQDMULH_LANE))]
3448 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3449 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]";
3451 [(set (attr "neon_type")
3452 (if_then_else (match_test "<Scalar_mul_8_16>")
3453 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3454 (const_string "neon_mul_qqd_32_scalar")))]
3457 (define_insn "neon_vqdmulh_lane<mode>"
3458 [(set (match_operand:VMDI 0 "s_register_operand" "=w")
3459 (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
3460 (match_operand:VMDI 2 "s_register_operand"
3461 "<scalar_mul_constraint>")
3462 (match_operand:SI 3 "immediate_operand" "i")
3463 (match_operand:SI 4 "immediate_operand" "i")]
3464 UNSPEC_VQDMULH_LANE))]
3467 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3468 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]";
3470 [(set (attr "neon_type")
3471 (if_then_else (match_test "<Scalar_mul_8_16>")
3472 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3473 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3476 (define_insn "neon_vmla_lane<mode>"
3477 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3478 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3479 (match_operand:VMD 2 "s_register_operand" "w")
3480 (match_operand:VMD 3 "s_register_operand"
3481 "<scalar_mul_constraint>")
3482 (match_operand:SI 4 "immediate_operand" "i")
3483 (match_operand:SI 5 "immediate_operand" "i")]
3487 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3488 return "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3490 [(set (attr "neon_type")
3491 (if_then_else (match_test "<Is_float_mode>")
3492 (const_string "neon_fp_vmla_ddd_scalar")
3493 (if_then_else (match_test "<Scalar_mul_8_16>")
3494 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3495 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3498 (define_insn "neon_vmla_lane<mode>"
3499 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3500 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3501 (match_operand:VMQ 2 "s_register_operand" "w")
3502 (match_operand:<V_HALF> 3 "s_register_operand"
3503 "<scalar_mul_constraint>")
3504 (match_operand:SI 4 "immediate_operand" "i")
3505 (match_operand:SI 5 "immediate_operand" "i")]
3509 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3510 return "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3512 [(set (attr "neon_type")
3513 (if_then_else (match_test "<Is_float_mode>")
3514 (const_string "neon_fp_vmla_qqq_scalar")
3515 (if_then_else (match_test "<Scalar_mul_8_16>")
3516 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3517 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3520 (define_insn "neon_vmlal_lane<mode>"
3521 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3522 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3523 (match_operand:VMDI 2 "s_register_operand" "w")
3524 (match_operand:VMDI 3 "s_register_operand"
3525 "<scalar_mul_constraint>")
3526 (match_operand:SI 4 "immediate_operand" "i")
3527 (match_operand:SI 5 "immediate_operand" "i")]
3528 UNSPEC_VMLAL_LANE))]
3531 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3532 return "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3534 [(set (attr "neon_type")
3535 (if_then_else (match_test "<Scalar_mul_8_16>")
3536 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3537 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3540 (define_insn "neon_vqdmlal_lane<mode>"
3541 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3542 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3543 (match_operand:VMDI 2 "s_register_operand" "w")
3544 (match_operand:VMDI 3 "s_register_operand"
3545 "<scalar_mul_constraint>")
3546 (match_operand:SI 4 "immediate_operand" "i")
3547 (match_operand:SI 5 "immediate_operand" "i")]
3548 UNSPEC_VQDMLAL_LANE))]
3551 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3552 return "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3554 [(set (attr "neon_type")
3555 (if_then_else (match_test "<Scalar_mul_8_16>")
3556 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3557 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3560 (define_insn "neon_vmls_lane<mode>"
3561 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3562 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3563 (match_operand:VMD 2 "s_register_operand" "w")
3564 (match_operand:VMD 3 "s_register_operand"
3565 "<scalar_mul_constraint>")
3566 (match_operand:SI 4 "immediate_operand" "i")
3567 (match_operand:SI 5 "immediate_operand" "i")]
3571 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3572 return "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3574 [(set (attr "neon_type")
3575 (if_then_else (match_test "<Is_float_mode>")
3576 (const_string "neon_fp_vmla_ddd_scalar")
3577 (if_then_else (match_test "<Scalar_mul_8_16>")
3578 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3579 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3582 (define_insn "neon_vmls_lane<mode>"
3583 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3584 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3585 (match_operand:VMQ 2 "s_register_operand" "w")
3586 (match_operand:<V_HALF> 3 "s_register_operand"
3587 "<scalar_mul_constraint>")
3588 (match_operand:SI 4 "immediate_operand" "i")
3589 (match_operand:SI 5 "immediate_operand" "i")]
3593 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3594 return "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3596 [(set (attr "neon_type")
3597 (if_then_else (match_test "<Is_float_mode>")
3598 (const_string "neon_fp_vmla_qqq_scalar")
3599 (if_then_else (match_test "<Scalar_mul_8_16>")
3600 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3601 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3604 (define_insn "neon_vmlsl_lane<mode>"
3605 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3606 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3607 (match_operand:VMDI 2 "s_register_operand" "w")
3608 (match_operand:VMDI 3 "s_register_operand"
3609 "<scalar_mul_constraint>")
3610 (match_operand:SI 4 "immediate_operand" "i")
3611 (match_operand:SI 5 "immediate_operand" "i")]
3612 UNSPEC_VMLSL_LANE))]
3615 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3616 return "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3618 [(set (attr "neon_type")
3619 (if_then_else (match_test "<Scalar_mul_8_16>")
3620 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3621 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3624 (define_insn "neon_vqdmlsl_lane<mode>"
3625 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3626 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3627 (match_operand:VMDI 2 "s_register_operand" "w")
3628 (match_operand:VMDI 3 "s_register_operand"
3629 "<scalar_mul_constraint>")
3630 (match_operand:SI 4 "immediate_operand" "i")
3631 (match_operand:SI 5 "immediate_operand" "i")]
3632 UNSPEC_VQDMLSL_LANE))]
3635 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3636 return "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3638 [(set (attr "neon_type")
3639 (if_then_else (match_test "<Scalar_mul_8_16>")
3640 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3641 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3644 ; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
3645 ; core register into a temp register, then use a scalar taken from that. This
3646 ; isn't an optimal solution if e.g. the scalar has just been read from memory
3647 ; or extracted from another vector. The latter case it's currently better to
3648 ; use the "_lane" variant, and the former case can probably be implemented
3649 ; using vld1_lane, but that hasn't been done yet.
3651 (define_expand "neon_vmul_n<mode>"
3652 [(match_operand:VMD 0 "s_register_operand" "")
3653 (match_operand:VMD 1 "s_register_operand" "")
3654 (match_operand:<V_elem> 2 "s_register_operand" "")
3655 (match_operand:SI 3 "immediate_operand" "")]
3658 rtx tmp = gen_reg_rtx (<MODE>mode);
3659 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3660 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3661 const0_rtx, const0_rtx));
3665 (define_expand "neon_vmul_n<mode>"
3666 [(match_operand:VMQ 0 "s_register_operand" "")
3667 (match_operand:VMQ 1 "s_register_operand" "")
3668 (match_operand:<V_elem> 2 "s_register_operand" "")
3669 (match_operand:SI 3 "immediate_operand" "")]
3672 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3673 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3674 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3675 const0_rtx, const0_rtx));
3679 (define_expand "neon_vmull_n<mode>"
3680 [(match_operand:<V_widen> 0 "s_register_operand" "")
3681 (match_operand:VMDI 1 "s_register_operand" "")
3682 (match_operand:<V_elem> 2 "s_register_operand" "")
3683 (match_operand:SI 3 "immediate_operand" "")]
3686 rtx tmp = gen_reg_rtx (<MODE>mode);
3687 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3688 emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp,
3689 const0_rtx, operands[3]));
3693 (define_expand "neon_vqdmull_n<mode>"
3694 [(match_operand:<V_widen> 0 "s_register_operand" "")
3695 (match_operand:VMDI 1 "s_register_operand" "")
3696 (match_operand:<V_elem> 2 "s_register_operand" "")
3697 (match_operand:SI 3 "immediate_operand" "")]
3700 rtx tmp = gen_reg_rtx (<MODE>mode);
3701 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3702 emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp,
3703 const0_rtx, const0_rtx));
3707 (define_expand "neon_vqdmulh_n<mode>"
3708 [(match_operand:VMDI 0 "s_register_operand" "")
3709 (match_operand:VMDI 1 "s_register_operand" "")
3710 (match_operand:<V_elem> 2 "s_register_operand" "")
3711 (match_operand:SI 3 "immediate_operand" "")]
3714 rtx tmp = gen_reg_rtx (<MODE>mode);
3715 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3716 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3717 const0_rtx, operands[3]));
3721 (define_expand "neon_vqdmulh_n<mode>"
3722 [(match_operand:VMQI 0 "s_register_operand" "")
3723 (match_operand:VMQI 1 "s_register_operand" "")
3724 (match_operand:<V_elem> 2 "s_register_operand" "")
3725 (match_operand:SI 3 "immediate_operand" "")]
3728 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3729 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3730 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3731 const0_rtx, operands[3]));
3735 (define_expand "neon_vmla_n<mode>"
3736 [(match_operand:VMD 0 "s_register_operand" "")
3737 (match_operand:VMD 1 "s_register_operand" "")
3738 (match_operand:VMD 2 "s_register_operand" "")
3739 (match_operand:<V_elem> 3 "s_register_operand" "")
3740 (match_operand:SI 4 "immediate_operand" "")]
3743 rtx tmp = gen_reg_rtx (<MODE>mode);
3744 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3745 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3746 tmp, const0_rtx, operands[4]));
3750 (define_expand "neon_vmla_n<mode>"
3751 [(match_operand:VMQ 0 "s_register_operand" "")
3752 (match_operand:VMQ 1 "s_register_operand" "")
3753 (match_operand:VMQ 2 "s_register_operand" "")
3754 (match_operand:<V_elem> 3 "s_register_operand" "")
3755 (match_operand:SI 4 "immediate_operand" "")]
3758 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3759 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3760 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3761 tmp, const0_rtx, operands[4]));
3765 (define_expand "neon_vmlal_n<mode>"
3766 [(match_operand:<V_widen> 0 "s_register_operand" "")
3767 (match_operand:<V_widen> 1 "s_register_operand" "")
3768 (match_operand:VMDI 2 "s_register_operand" "")
3769 (match_operand:<V_elem> 3 "s_register_operand" "")
3770 (match_operand:SI 4 "immediate_operand" "")]
3773 rtx tmp = gen_reg_rtx (<MODE>mode);
3774 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3775 emit_insn (gen_neon_vmlal_lane<mode> (operands[0], operands[1], operands[2],
3776 tmp, const0_rtx, operands[4]));
3780 (define_expand "neon_vqdmlal_n<mode>"
3781 [(match_operand:<V_widen> 0 "s_register_operand" "")
3782 (match_operand:<V_widen> 1 "s_register_operand" "")
3783 (match_operand:VMDI 2 "s_register_operand" "")
3784 (match_operand:<V_elem> 3 "s_register_operand" "")
3785 (match_operand:SI 4 "immediate_operand" "")]
3788 rtx tmp = gen_reg_rtx (<MODE>mode);
3789 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3790 emit_insn (gen_neon_vqdmlal_lane<mode> (operands[0], operands[1], operands[2],
3791 tmp, const0_rtx, operands[4]));
3795 (define_expand "neon_vmls_n<mode>"
3796 [(match_operand:VMD 0 "s_register_operand" "")
3797 (match_operand:VMD 1 "s_register_operand" "")
3798 (match_operand:VMD 2 "s_register_operand" "")
3799 (match_operand:<V_elem> 3 "s_register_operand" "")
3800 (match_operand:SI 4 "immediate_operand" "")]
3803 rtx tmp = gen_reg_rtx (<MODE>mode);
3804 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3805 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3806 tmp, const0_rtx, operands[4]));
3810 (define_expand "neon_vmls_n<mode>"
3811 [(match_operand:VMQ 0 "s_register_operand" "")
3812 (match_operand:VMQ 1 "s_register_operand" "")
3813 (match_operand:VMQ 2 "s_register_operand" "")
3814 (match_operand:<V_elem> 3 "s_register_operand" "")
3815 (match_operand:SI 4 "immediate_operand" "")]
3818 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3819 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3820 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3821 tmp, const0_rtx, operands[4]));
3825 (define_expand "neon_vmlsl_n<mode>"
3826 [(match_operand:<V_widen> 0 "s_register_operand" "")
3827 (match_operand:<V_widen> 1 "s_register_operand" "")
3828 (match_operand:VMDI 2 "s_register_operand" "")
3829 (match_operand:<V_elem> 3 "s_register_operand" "")
3830 (match_operand:SI 4 "immediate_operand" "")]
3833 rtx tmp = gen_reg_rtx (<MODE>mode);
3834 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3835 emit_insn (gen_neon_vmlsl_lane<mode> (operands[0], operands[1], operands[2],
3836 tmp, const0_rtx, operands[4]));
3840 (define_expand "neon_vqdmlsl_n<mode>"
3841 [(match_operand:<V_widen> 0 "s_register_operand" "")
3842 (match_operand:<V_widen> 1 "s_register_operand" "")
3843 (match_operand:VMDI 2 "s_register_operand" "")
3844 (match_operand:<V_elem> 3 "s_register_operand" "")
3845 (match_operand:SI 4 "immediate_operand" "")]
3848 rtx tmp = gen_reg_rtx (<MODE>mode);
3849 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3850 emit_insn (gen_neon_vqdmlsl_lane<mode> (operands[0], operands[1], operands[2],
3851 tmp, const0_rtx, operands[4]));
3855 (define_insn "neon_vext<mode>"
3856 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
3857 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
3858 (match_operand:VDQX 2 "s_register_operand" "w")
3859 (match_operand:SI 3 "immediate_operand" "i")]
3863 neon_const_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3864 return "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3";
3866 [(set (attr "neon_type")
3867 (if_then_else (match_test "<Is_d_reg>")
3868 (const_string "neon_bp_simple")
3869 (const_string "neon_bp_2cycle")))]
3872 (define_insn "neon_vrev64<mode>"
3873 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
3874 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
3875 (match_operand:SI 2 "immediate_operand" "i")]
3878 "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3879 [(set_attr "neon_type" "neon_bp_simple")]
3882 (define_insn "neon_vrev32<mode>"
3883 [(set (match_operand:VX 0 "s_register_operand" "=w")
3884 (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")
3885 (match_operand:SI 2 "immediate_operand" "i")]
3888 "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3889 [(set_attr "neon_type" "neon_bp_simple")]
3892 (define_insn "neon_vrev16<mode>"
3893 [(set (match_operand:VE 0 "s_register_operand" "=w")
3894 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
3895 (match_operand:SI 2 "immediate_operand" "i")]
3898 "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3899 [(set_attr "neon_type" "neon_bp_simple")]
3902 ; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
3903 ; allocation. For an intrinsic of form:
3904 ; rD = vbsl_* (rS, rN, rM)
3905 ; We can use any of:
3906 ; vbsl rS, rN, rM (if D = S)
3907 ; vbit rD, rN, rS (if D = M, so 1-bits in rS choose bits from rN, else rM)
3908 ; vbif rD, rM, rS (if D = N, so 0-bits in rS choose bits from rM, else rN)
3910 (define_insn "neon_vbsl<mode>_internal"
3911 [(set (match_operand:VDQX 0 "s_register_operand" "=w,w,w")
3912 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" " 0,w,w")
3913 (match_operand:VDQX 2 "s_register_operand" " w,w,0")
3914 (match_operand:VDQX 3 "s_register_operand" " w,0,w")]
3918 vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3
3919 vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1
3920 vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1"
3921 [(set_attr "neon_type" "neon_int_1")]
3924 (define_expand "neon_vbsl<mode>"
3925 [(set (match_operand:VDQX 0 "s_register_operand" "")
3926 (unspec:VDQX [(match_operand:<V_cmp_result> 1 "s_register_operand" "")
3927 (match_operand:VDQX 2 "s_register_operand" "")
3928 (match_operand:VDQX 3 "s_register_operand" "")]
3932 /* We can't alias operands together if they have different modes. */
3933 operands[1] = gen_lowpart (<MODE>mode, operands[1]);
3936 (define_insn "neon_vshl<mode>"
3937 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3938 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3939 (match_operand:VDQIX 2 "s_register_operand" "w")
3940 (match_operand:SI 3 "immediate_operand" "i")]
3943 "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3944 [(set (attr "neon_type")
3945 (if_then_else (match_test "<Is_d_reg>")
3946 (const_string "neon_vshl_ddd")
3947 (const_string "neon_shift_3")))]
3950 (define_insn "neon_vqshl<mode>"
3951 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3952 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3953 (match_operand:VDQIX 2 "s_register_operand" "w")
3954 (match_operand:SI 3 "immediate_operand" "i")]
3957 "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3958 [(set (attr "neon_type")
3959 (if_then_else (match_test "<Is_d_reg>")
3960 (const_string "neon_shift_2")
3961 (const_string "neon_vqshl_vrshl_vqrshl_qqq")))]
3964 (define_insn "neon_vshr_n<mode>"
3965 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3966 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3967 (match_operand:SI 2 "immediate_operand" "i")
3968 (match_operand:SI 3 "immediate_operand" "i")]
3972 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) + 1);
3973 return "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3975 [(set_attr "neon_type" "neon_shift_1")]
3978 (define_insn "neon_vshrn_n<mode>"
3979 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3980 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3981 (match_operand:SI 2 "immediate_operand" "i")
3982 (match_operand:SI 3 "immediate_operand" "i")]
3986 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3987 return "v%O3shrn.<V_if_elem>\t%P0, %q1, %2";
3989 [(set_attr "neon_type" "neon_shift_1")]
3992 (define_insn "neon_vqshrn_n<mode>"
3993 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3994 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3995 (match_operand:SI 2 "immediate_operand" "i")
3996 (match_operand:SI 3 "immediate_operand" "i")]
4000 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
4001 return "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2";
4003 [(set_attr "neon_type" "neon_shift_2")]
4006 (define_insn "neon_vqshrun_n<mode>"
4007 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
4008 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
4009 (match_operand:SI 2 "immediate_operand" "i")
4010 (match_operand:SI 3 "immediate_operand" "i")]
4014 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
4015 return "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2";
4017 [(set_attr "neon_type" "neon_shift_2")]
4020 (define_insn "neon_vshl_n<mode>"
4021 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4022 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
4023 (match_operand:SI 2 "immediate_operand" "i")
4024 (match_operand:SI 3 "immediate_operand" "i")]
4028 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
4029 return "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2";
4031 [(set_attr "neon_type" "neon_shift_1")]
4034 (define_insn "neon_vqshl_n<mode>"
4035 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4036 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
4037 (match_operand:SI 2 "immediate_operand" "i")
4038 (match_operand:SI 3 "immediate_operand" "i")]
4042 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
4043 return "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
4045 [(set_attr "neon_type" "neon_shift_2")]
4048 (define_insn "neon_vqshlu_n<mode>"
4049 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4050 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
4051 (match_operand:SI 2 "immediate_operand" "i")
4052 (match_operand:SI 3 "immediate_operand" "i")]
4056 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
4057 return "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
4059 [(set_attr "neon_type" "neon_shift_2")]
4062 (define_insn "neon_vshll_n<mode>"
4063 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
4064 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
4065 (match_operand:SI 2 "immediate_operand" "i")
4066 (match_operand:SI 3 "immediate_operand" "i")]
4070 /* The boundaries are: 0 < imm <= size. */
4071 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode) + 1);
4072 return "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2";
4074 [(set_attr "neon_type" "neon_shift_1")]
4077 (define_insn "neon_vsra_n<mode>"
4078 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4079 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4080 (match_operand:VDQIX 2 "s_register_operand" "w")
4081 (match_operand:SI 3 "immediate_operand" "i")
4082 (match_operand:SI 4 "immediate_operand" "i")]
4086 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
4087 return "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4089 [(set_attr "neon_type" "neon_vsra_vrsra")]
4092 (define_insn "neon_vsri_n<mode>"
4093 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4094 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4095 (match_operand:VDQIX 2 "s_register_operand" "w")
4096 (match_operand:SI 3 "immediate_operand" "i")]
4100 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
4101 return "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4103 [(set (attr "neon_type")
4104 (if_then_else (match_test "<Is_d_reg>")
4105 (const_string "neon_shift_1")
4106 (const_string "neon_shift_3")))]
4109 (define_insn "neon_vsli_n<mode>"
4110 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4111 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4112 (match_operand:VDQIX 2 "s_register_operand" "w")
4113 (match_operand:SI 3 "immediate_operand" "i")]
4117 neon_const_bounds (operands[3], 0, neon_element_bits (<MODE>mode));
4118 return "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4120 [(set (attr "neon_type")
4121 (if_then_else (match_test "<Is_d_reg>")
4122 (const_string "neon_shift_1")
4123 (const_string "neon_shift_3")))]
4126 (define_insn "neon_vtbl1v8qi"
4127 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4128 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")
4129 (match_operand:V8QI 2 "s_register_operand" "w")]
4132 "vtbl.8\t%P0, {%P1}, %P2"
4133 [(set_attr "neon_type" "neon_bp_2cycle")]
4136 (define_insn "neon_vtbl2v8qi"
4137 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4138 (unspec:V8QI [(match_operand:TI 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] = operands[2];
4150 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2}, %P3", ops);
4154 [(set_attr "neon_type" "neon_bp_2cycle")]
4157 (define_insn "neon_vtbl3v8qi"
4158 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4159 (unspec:V8QI [(match_operand:EI 1 "s_register_operand" "w")
4160 (match_operand:V8QI 2 "s_register_operand" "w")]
4165 int tabbase = REGNO (operands[1]);
4167 ops[0] = operands[0];
4168 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4169 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4170 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4171 ops[4] = operands[2];
4172 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
4176 [(set_attr "neon_type" "neon_bp_3cycle")]
4179 (define_insn "neon_vtbl4v8qi"
4180 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4181 (unspec:V8QI [(match_operand:OI 1 "s_register_operand" "w")
4182 (match_operand:V8QI 2 "s_register_operand" "w")]
4187 int tabbase = REGNO (operands[1]);
4189 ops[0] = operands[0];
4190 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4191 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4192 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4193 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4194 ops[5] = operands[2];
4195 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4199 [(set_attr "neon_type" "neon_bp_3cycle")]
4202 ;; These three are used by the vec_perm infrastructure for V16QImode.
4203 (define_insn_and_split "neon_vtbl1v16qi"
4204 [(set (match_operand:V16QI 0 "s_register_operand" "=&w")
4205 (unspec:V16QI [(match_operand:V16QI 1 "s_register_operand" "w")
4206 (match_operand:V16QI 2 "s_register_operand" "w")]
4210 "&& reload_completed"
4213 rtx op0, op1, op2, part0, part2;
4217 op1 = gen_lowpart (TImode, operands[1]);
4220 ofs = subreg_lowpart_offset (V8QImode, V16QImode);
4221 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4222 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4223 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4225 ofs = subreg_highpart_offset (V8QImode, V16QImode);
4226 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4227 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4228 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4232 (define_insn_and_split "neon_vtbl2v16qi"
4233 [(set (match_operand:V16QI 0 "s_register_operand" "=&w")
4234 (unspec:V16QI [(match_operand:OI 1 "s_register_operand" "w")
4235 (match_operand:V16QI 2 "s_register_operand" "w")]
4239 "&& reload_completed"
4242 rtx op0, op1, op2, part0, part2;
4249 ofs = subreg_lowpart_offset (V8QImode, V16QImode);
4250 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4251 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4252 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4254 ofs = subreg_highpart_offset (V8QImode, V16QImode);
4255 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4256 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4257 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4261 ;; ??? Logically we should extend the regular neon_vcombine pattern to
4262 ;; handle quad-word input modes, producing octa-word output modes. But
4263 ;; that requires us to add support for octa-word vector modes in moves.
4264 ;; That seems overkill for this one use in vec_perm.
4265 (define_insn_and_split "neon_vcombinev16qi"
4266 [(set (match_operand:OI 0 "s_register_operand" "=w")
4267 (unspec:OI [(match_operand:V16QI 1 "s_register_operand" "w")
4268 (match_operand:V16QI 2 "s_register_operand" "w")]
4272 "&& reload_completed"
4275 neon_split_vcombine (operands);
4279 (define_insn "neon_vtbx1v8qi"
4280 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4281 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4282 (match_operand:V8QI 2 "s_register_operand" "w")
4283 (match_operand:V8QI 3 "s_register_operand" "w")]
4286 "vtbx.8\t%P0, {%P2}, %P3"
4287 [(set_attr "neon_type" "neon_bp_2cycle")]
4290 (define_insn "neon_vtbx2v8qi"
4291 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4292 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4293 (match_operand:TI 2 "s_register_operand" "w")
4294 (match_operand:V8QI 3 "s_register_operand" "w")]
4299 int tabbase = REGNO (operands[2]);
4301 ops[0] = operands[0];
4302 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4303 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4304 ops[3] = operands[3];
4305 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2}, %P3", ops);
4309 [(set_attr "neon_type" "neon_bp_2cycle")]
4312 (define_insn "neon_vtbx3v8qi"
4313 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4314 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4315 (match_operand:EI 2 "s_register_operand" "w")
4316 (match_operand:V8QI 3 "s_register_operand" "w")]
4321 int tabbase = REGNO (operands[2]);
4323 ops[0] = operands[0];
4324 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4325 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4326 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4327 ops[4] = operands[3];
4328 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
4332 [(set_attr "neon_type" "neon_bp_3cycle")]
4335 (define_insn "neon_vtbx4v8qi"
4336 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4337 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4338 (match_operand:OI 2 "s_register_operand" "w")
4339 (match_operand:V8QI 3 "s_register_operand" "w")]
4344 int tabbase = REGNO (operands[2]);
4346 ops[0] = operands[0];
4347 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4348 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4349 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4350 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4351 ops[5] = operands[3];
4352 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4356 [(set_attr "neon_type" "neon_bp_3cycle")]
4359 (define_expand "neon_vtrn<mode>_internal"
4361 [(set (match_operand:VDQW 0 "s_register_operand" "")
4362 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4363 (match_operand:VDQW 2 "s_register_operand" "")]
4365 (set (match_operand:VDQW 3 "s_register_operand" "")
4366 (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VTRN2))])]
4371 ;; Note: Different operand numbering to handle tied registers correctly.
4372 (define_insn "*neon_vtrn<mode>_insn"
4373 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4374 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4375 (match_operand:VDQW 3 "s_register_operand" "2")]
4377 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4378 (unspec:VDQW [(match_dup 1) (match_dup 3)]
4381 "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4382 [(set (attr "neon_type")
4383 (if_then_else (match_test "<Is_d_reg>")
4384 (const_string "neon_bp_simple")
4385 (const_string "neon_bp_3cycle")))]
4388 (define_expand "neon_vtrn<mode>"
4389 [(match_operand:SI 0 "s_register_operand" "r")
4390 (match_operand:VDQW 1 "s_register_operand" "w")
4391 (match_operand:VDQW 2 "s_register_operand" "w")]
4394 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vtrn<mode>_internal,
4395 operands[0], operands[1], operands[2]);
4399 (define_expand "neon_vzip<mode>_internal"
4401 [(set (match_operand:VDQW 0 "s_register_operand" "")
4402 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4403 (match_operand:VDQW 2 "s_register_operand" "")]
4405 (set (match_operand:VDQW 3 "s_register_operand" "")
4406 (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VZIP2))])]
4411 ;; Note: Different operand numbering to handle tied registers correctly.
4412 (define_insn "*neon_vzip<mode>_insn"
4413 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4414 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4415 (match_operand:VDQW 3 "s_register_operand" "2")]
4417 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4418 (unspec:VDQW [(match_dup 1) (match_dup 3)]
4421 "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4422 [(set (attr "neon_type")
4423 (if_then_else (match_test "<Is_d_reg>")
4424 (const_string "neon_bp_simple")
4425 (const_string "neon_bp_3cycle")))]
4428 (define_expand "neon_vzip<mode>"
4429 [(match_operand:SI 0 "s_register_operand" "r")
4430 (match_operand:VDQW 1 "s_register_operand" "w")
4431 (match_operand:VDQW 2 "s_register_operand" "w")]
4434 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vzip<mode>_internal,
4435 operands[0], operands[1], operands[2]);
4439 (define_expand "neon_vuzp<mode>_internal"
4441 [(set (match_operand:VDQW 0 "s_register_operand" "")
4442 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4443 (match_operand:VDQW 2 "s_register_operand" "")]
4445 (set (match_operand:VDQW 3 "s_register_operand" "")
4446 (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VUZP2))])]
4451 ;; Note: Different operand numbering to handle tied registers correctly.
4452 (define_insn "*neon_vuzp<mode>_insn"
4453 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4454 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4455 (match_operand:VDQW 3 "s_register_operand" "2")]
4457 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4458 (unspec:VDQW [(match_dup 1) (match_dup 3)]
4461 "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4462 [(set (attr "neon_type")
4463 (if_then_else (match_test "<Is_d_reg>")
4464 (const_string "neon_bp_simple")
4465 (const_string "neon_bp_3cycle")))]
4468 (define_expand "neon_vuzp<mode>"
4469 [(match_operand:SI 0 "s_register_operand" "r")
4470 (match_operand:VDQW 1 "s_register_operand" "w")
4471 (match_operand:VDQW 2 "s_register_operand" "w")]
4474 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vuzp<mode>_internal,
4475 operands[0], operands[1], operands[2]);
4479 (define_expand "neon_vreinterpretv8qi<mode>"
4480 [(match_operand:V8QI 0 "s_register_operand" "")
4481 (match_operand:VDX 1 "s_register_operand" "")]
4484 neon_reinterpret (operands[0], operands[1]);
4488 (define_expand "neon_vreinterpretv4hi<mode>"
4489 [(match_operand:V4HI 0 "s_register_operand" "")
4490 (match_operand:VDX 1 "s_register_operand" "")]
4493 neon_reinterpret (operands[0], operands[1]);
4497 (define_expand "neon_vreinterpretv2si<mode>"
4498 [(match_operand:V2SI 0 "s_register_operand" "")
4499 (match_operand:VDX 1 "s_register_operand" "")]
4502 neon_reinterpret (operands[0], operands[1]);
4506 (define_expand "neon_vreinterpretv2sf<mode>"
4507 [(match_operand:V2SF 0 "s_register_operand" "")
4508 (match_operand:VDX 1 "s_register_operand" "")]
4511 neon_reinterpret (operands[0], operands[1]);
4515 (define_expand "neon_vreinterpretdi<mode>"
4516 [(match_operand:DI 0 "s_register_operand" "")
4517 (match_operand:VDX 1 "s_register_operand" "")]
4520 neon_reinterpret (operands[0], operands[1]);
4524 (define_expand "neon_vreinterpretv16qi<mode>"
4525 [(match_operand:V16QI 0 "s_register_operand" "")
4526 (match_operand:VQX 1 "s_register_operand" "")]
4529 neon_reinterpret (operands[0], operands[1]);
4533 (define_expand "neon_vreinterpretv8hi<mode>"
4534 [(match_operand:V8HI 0 "s_register_operand" "")
4535 (match_operand:VQX 1 "s_register_operand" "")]
4538 neon_reinterpret (operands[0], operands[1]);
4542 (define_expand "neon_vreinterpretv4si<mode>"
4543 [(match_operand:V4SI 0 "s_register_operand" "")
4544 (match_operand:VQX 1 "s_register_operand" "")]
4547 neon_reinterpret (operands[0], operands[1]);
4551 (define_expand "neon_vreinterpretv4sf<mode>"
4552 [(match_operand:V4SF 0 "s_register_operand" "")
4553 (match_operand:VQX 1 "s_register_operand" "")]
4556 neon_reinterpret (operands[0], operands[1]);
4560 (define_expand "neon_vreinterpretv2di<mode>"
4561 [(match_operand:V2DI 0 "s_register_operand" "")
4562 (match_operand:VQX 1 "s_register_operand" "")]
4565 neon_reinterpret (operands[0], operands[1]);
4569 (define_expand "vec_load_lanes<mode><mode>"
4570 [(set (match_operand:VDQX 0 "s_register_operand")
4571 (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_operand")]
4575 (define_insn "neon_vld1<mode>"
4576 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
4577 (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_operand" "Um")]
4580 "vld1.<V_sz_elem>\t%h0, %A1"
4581 [(set_attr "neon_type" "neon_vld1_1_2_regs")]
4584 (define_insn "neon_vld1_lane<mode>"
4585 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4586 (unspec:VDX [(match_operand:<V_elem> 1 "neon_struct_operand" "Um")
4587 (match_operand:VDX 2 "s_register_operand" "0")
4588 (match_operand:SI 3 "immediate_operand" "i")]
4592 HOST_WIDE_INT lane = INTVAL (operands[3]);
4593 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4594 if (lane < 0 || lane >= max)
4595 error ("lane out of range");
4597 return "vld1.<V_sz_elem>\t%P0, %A1";
4599 return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1";
4601 [(set (attr "neon_type")
4602 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4603 (const_string "neon_vld1_1_2_regs")
4604 (const_string "neon_vld1_vld2_lane")))]
4607 (define_insn "neon_vld1_lane<mode>"
4608 [(set (match_operand:VQX 0 "s_register_operand" "=w")
4609 (unspec:VQX [(match_operand:<V_elem> 1 "neon_struct_operand" "Um")
4610 (match_operand:VQX 2 "s_register_operand" "0")
4611 (match_operand:SI 3 "immediate_operand" "i")]
4615 HOST_WIDE_INT lane = INTVAL (operands[3]);
4616 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4617 int regno = REGNO (operands[0]);
4618 if (lane < 0 || lane >= max)
4619 error ("lane out of range");
4620 else if (lane >= max / 2)
4624 operands[3] = GEN_INT (lane);
4626 operands[0] = gen_rtx_REG (<V_HALF>mode, regno);
4628 return "vld1.<V_sz_elem>\t%P0, %A1";
4630 return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1";
4632 [(set (attr "neon_type")
4633 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4634 (const_string "neon_vld1_1_2_regs")
4635 (const_string "neon_vld1_vld2_lane")))]
4638 (define_insn "neon_vld1_dup<mode>"
4639 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4640 (vec_duplicate:VDX (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
4643 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4644 return "vld1.<V_sz_elem>\t{%P0[]}, %A1";
4646 return "vld1.<V_sz_elem>\t%h0, %A1";
4648 [(set (attr "neon_type")
4649 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4650 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4651 (const_string "neon_vld1_1_2_regs")))]
4654 (define_insn "neon_vld1_dup<mode>"
4655 [(set (match_operand:VQ 0 "s_register_operand" "=w")
4656 (vec_duplicate:VQ (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
4659 return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, %A1";
4661 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
4664 (define_insn_and_split "neon_vld1_dupv2di"
4665 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
4666 (vec_duplicate:V2DI (match_operand:DI 1 "neon_struct_operand" "Um")))]
4669 "&& reload_completed"
4672 rtx tmprtx = gen_lowpart (DImode, operands[0]);
4673 emit_insn (gen_neon_vld1_dupdi (tmprtx, operands[1]));
4674 emit_move_insn (gen_highpart (DImode, operands[0]), tmprtx );
4677 [(set_attr "length" "8")
4678 (set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
4681 (define_expand "vec_store_lanes<mode><mode>"
4682 [(set (match_operand:VDQX 0 "neon_struct_operand")
4683 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand")]
4687 (define_insn "neon_vst1<mode>"
4688 [(set (match_operand:VDQX 0 "neon_struct_operand" "=Um")
4689 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")]
4692 "vst1.<V_sz_elem>\t%h1, %A0"
4693 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
4695 (define_insn "neon_vst1_lane<mode>"
4696 [(set (match_operand:<V_elem> 0 "neon_struct_operand" "=Um")
4698 [(match_operand:VDX 1 "s_register_operand" "w")
4699 (match_operand:SI 2 "immediate_operand" "i")]
4703 HOST_WIDE_INT lane = INTVAL (operands[2]);
4704 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4705 if (lane < 0 || lane >= max)
4706 error ("lane out of range");
4708 return "vst1.<V_sz_elem>\t{%P1}, %A0";
4710 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
4712 [(set (attr "neon_type")
4713 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 1))
4714 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4715 (const_string "neon_vst1_vst2_lane")))])
4717 (define_insn "neon_vst1_lane<mode>"
4718 [(set (match_operand:<V_elem> 0 "neon_struct_operand" "=Um")
4720 [(match_operand:VQX 1 "s_register_operand" "w")
4721 (match_operand:SI 2 "immediate_operand" "i")]
4725 HOST_WIDE_INT lane = INTVAL (operands[2]);
4726 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4727 int regno = REGNO (operands[1]);
4728 if (lane < 0 || lane >= max)
4729 error ("lane out of range");
4730 else if (lane >= max / 2)
4734 operands[2] = GEN_INT (lane);
4736 operands[1] = gen_rtx_REG (<V_HALF>mode, regno);
4738 return "vst1.<V_sz_elem>\t{%P1}, %A0";
4740 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
4742 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4745 (define_expand "vec_load_lanesti<mode>"
4746 [(set (match_operand:TI 0 "s_register_operand")
4747 (unspec:TI [(match_operand:TI 1 "neon_struct_operand")
4748 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4752 (define_insn "neon_vld2<mode>"
4753 [(set (match_operand:TI 0 "s_register_operand" "=w")
4754 (unspec:TI [(match_operand:TI 1 "neon_struct_operand" "Um")
4755 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4759 if (<V_sz_elem> == 64)
4760 return "vld1.64\t%h0, %A1";
4762 return "vld2.<V_sz_elem>\t%h0, %A1";
4764 [(set (attr "neon_type")
4765 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4766 (const_string "neon_vld1_1_2_regs")
4767 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))]
4770 (define_expand "vec_load_lanesoi<mode>"
4771 [(set (match_operand:OI 0 "s_register_operand")
4772 (unspec:OI [(match_operand:OI 1 "neon_struct_operand")
4773 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4777 (define_insn "neon_vld2<mode>"
4778 [(set (match_operand:OI 0 "s_register_operand" "=w")
4779 (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um")
4780 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4783 "vld2.<V_sz_elem>\t%h0, %A1"
4784 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")])
4786 (define_insn "neon_vld2_lane<mode>"
4787 [(set (match_operand:TI 0 "s_register_operand" "=w")
4788 (unspec:TI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4789 (match_operand:TI 2 "s_register_operand" "0")
4790 (match_operand:SI 3 "immediate_operand" "i")
4791 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4795 HOST_WIDE_INT lane = INTVAL (operands[3]);
4796 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4797 int regno = REGNO (operands[0]);
4799 if (lane < 0 || lane >= max)
4800 error ("lane out of range");
4801 ops[0] = gen_rtx_REG (DImode, regno);
4802 ops[1] = gen_rtx_REG (DImode, regno + 2);
4803 ops[2] = operands[1];
4804 ops[3] = operands[3];
4805 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops);
4808 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4811 (define_insn "neon_vld2_lane<mode>"
4812 [(set (match_operand:OI 0 "s_register_operand" "=w")
4813 (unspec:OI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4814 (match_operand:OI 2 "s_register_operand" "0")
4815 (match_operand:SI 3 "immediate_operand" "i")
4816 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4820 HOST_WIDE_INT lane = INTVAL (operands[3]);
4821 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4822 int regno = REGNO (operands[0]);
4824 if (lane < 0 || lane >= max)
4825 error ("lane out of range");
4826 else if (lane >= max / 2)
4831 ops[0] = gen_rtx_REG (DImode, regno);
4832 ops[1] = gen_rtx_REG (DImode, regno + 4);
4833 ops[2] = operands[1];
4834 ops[3] = GEN_INT (lane);
4835 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops);
4838 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4841 (define_insn "neon_vld2_dup<mode>"
4842 [(set (match_operand:TI 0 "s_register_operand" "=w")
4843 (unspec:TI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4844 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4848 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4849 return "vld2.<V_sz_elem>\t{%e0[], %f0[]}, %A1";
4851 return "vld1.<V_sz_elem>\t%h0, %A1";
4853 [(set (attr "neon_type")
4854 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4855 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4856 (const_string "neon_vld1_1_2_regs")))]
4859 (define_expand "vec_store_lanesti<mode>"
4860 [(set (match_operand:TI 0 "neon_struct_operand")
4861 (unspec:TI [(match_operand:TI 1 "s_register_operand")
4862 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4866 (define_insn "neon_vst2<mode>"
4867 [(set (match_operand:TI 0 "neon_struct_operand" "=Um")
4868 (unspec:TI [(match_operand:TI 1 "s_register_operand" "w")
4869 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4873 if (<V_sz_elem> == 64)
4874 return "vst1.64\t%h1, %A0";
4876 return "vst2.<V_sz_elem>\t%h1, %A0";
4878 [(set (attr "neon_type")
4879 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4880 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4881 (const_string "neon_vst1_1_2_regs_vst2_2_regs")))]
4884 (define_expand "vec_store_lanesoi<mode>"
4885 [(set (match_operand:OI 0 "neon_struct_operand")
4886 (unspec:OI [(match_operand:OI 1 "s_register_operand")
4887 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4891 (define_insn "neon_vst2<mode>"
4892 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
4893 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4894 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4897 "vst2.<V_sz_elem>\t%h1, %A0"
4898 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]
4901 (define_insn "neon_vst2_lane<mode>"
4902 [(set (match_operand:<V_two_elem> 0 "neon_struct_operand" "=Um")
4903 (unspec:<V_two_elem>
4904 [(match_operand:TI 1 "s_register_operand" "w")
4905 (match_operand:SI 2 "immediate_operand" "i")
4906 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4910 HOST_WIDE_INT lane = INTVAL (operands[2]);
4911 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4912 int regno = REGNO (operands[1]);
4914 if (lane < 0 || lane >= max)
4915 error ("lane out of range");
4916 ops[0] = operands[0];
4917 ops[1] = gen_rtx_REG (DImode, regno);
4918 ops[2] = gen_rtx_REG (DImode, regno + 2);
4919 ops[3] = operands[2];
4920 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops);
4923 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4926 (define_insn "neon_vst2_lane<mode>"
4927 [(set (match_operand:<V_two_elem> 0 "neon_struct_operand" "=Um")
4928 (unspec:<V_two_elem>
4929 [(match_operand:OI 1 "s_register_operand" "w")
4930 (match_operand:SI 2 "immediate_operand" "i")
4931 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4935 HOST_WIDE_INT lane = INTVAL (operands[2]);
4936 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4937 int regno = REGNO (operands[1]);
4939 if (lane < 0 || lane >= max)
4940 error ("lane out of range");
4941 else if (lane >= max / 2)
4946 ops[0] = operands[0];
4947 ops[1] = gen_rtx_REG (DImode, regno);
4948 ops[2] = gen_rtx_REG (DImode, regno + 4);
4949 ops[3] = GEN_INT (lane);
4950 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops);
4953 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4956 (define_expand "vec_load_lanesei<mode>"
4957 [(set (match_operand:EI 0 "s_register_operand")
4958 (unspec:EI [(match_operand:EI 1 "neon_struct_operand")
4959 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4963 (define_insn "neon_vld3<mode>"
4964 [(set (match_operand:EI 0 "s_register_operand" "=w")
4965 (unspec:EI [(match_operand:EI 1 "neon_struct_operand" "Um")
4966 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4970 if (<V_sz_elem> == 64)
4971 return "vld1.64\t%h0, %A1";
4973 return "vld3.<V_sz_elem>\t%h0, %A1";
4975 [(set (attr "neon_type")
4976 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4977 (const_string "neon_vld1_1_2_regs")
4978 (const_string "neon_vld3_vld4")))]
4981 (define_expand "vec_load_lanesci<mode>"
4982 [(match_operand:CI 0 "s_register_operand")
4983 (match_operand:CI 1 "neon_struct_operand")
4984 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4987 emit_insn (gen_neon_vld3<mode> (operands[0], operands[1]));
4991 (define_expand "neon_vld3<mode>"
4992 [(match_operand:CI 0 "s_register_operand")
4993 (match_operand:CI 1 "neon_struct_operand")
4994 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4999 mem = adjust_address (operands[1], EImode, 0);
5000 emit_insn (gen_neon_vld3qa<mode> (operands[0], mem));
5001 mem = adjust_address (mem, EImode, GET_MODE_SIZE (EImode));
5002 emit_insn (gen_neon_vld3qb<mode> (operands[0], mem, operands[0]));
5006 (define_insn "neon_vld3qa<mode>"
5007 [(set (match_operand:CI 0 "s_register_operand" "=w")
5008 (unspec:CI [(match_operand:EI 1 "neon_struct_operand" "Um")
5009 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5013 int regno = REGNO (operands[0]);
5015 ops[0] = gen_rtx_REG (DImode, regno);
5016 ops[1] = gen_rtx_REG (DImode, regno + 4);
5017 ops[2] = gen_rtx_REG (DImode, regno + 8);
5018 ops[3] = operands[1];
5019 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops);
5022 [(set_attr "neon_type" "neon_vld3_vld4")]
5025 (define_insn "neon_vld3qb<mode>"
5026 [(set (match_operand:CI 0 "s_register_operand" "=w")
5027 (unspec:CI [(match_operand:EI 1 "neon_struct_operand" "Um")
5028 (match_operand:CI 2 "s_register_operand" "0")
5029 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5033 int regno = REGNO (operands[0]);
5035 ops[0] = gen_rtx_REG (DImode, regno + 2);
5036 ops[1] = gen_rtx_REG (DImode, regno + 6);
5037 ops[2] = gen_rtx_REG (DImode, regno + 10);
5038 ops[3] = operands[1];
5039 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops);
5042 [(set_attr "neon_type" "neon_vld3_vld4")]
5045 (define_insn "neon_vld3_lane<mode>"
5046 [(set (match_operand:EI 0 "s_register_operand" "=w")
5047 (unspec:EI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5048 (match_operand:EI 2 "s_register_operand" "0")
5049 (match_operand:SI 3 "immediate_operand" "i")
5050 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5054 HOST_WIDE_INT lane = INTVAL (operands[3]);
5055 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5056 int regno = REGNO (operands[0]);
5058 if (lane < 0 || lane >= max)
5059 error ("lane out of range");
5060 ops[0] = gen_rtx_REG (DImode, regno);
5061 ops[1] = gen_rtx_REG (DImode, regno + 2);
5062 ops[2] = gen_rtx_REG (DImode, regno + 4);
5063 ops[3] = operands[1];
5064 ops[4] = operands[3];
5065 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, %3",
5069 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5072 (define_insn "neon_vld3_lane<mode>"
5073 [(set (match_operand:CI 0 "s_register_operand" "=w")
5074 (unspec:CI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5075 (match_operand:CI 2 "s_register_operand" "0")
5076 (match_operand:SI 3 "immediate_operand" "i")
5077 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5081 HOST_WIDE_INT lane = INTVAL (operands[3]);
5082 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5083 int regno = REGNO (operands[0]);
5085 if (lane < 0 || lane >= max)
5086 error ("lane out of range");
5087 else if (lane >= max / 2)
5092 ops[0] = gen_rtx_REG (DImode, regno);
5093 ops[1] = gen_rtx_REG (DImode, regno + 4);
5094 ops[2] = gen_rtx_REG (DImode, regno + 8);
5095 ops[3] = operands[1];
5096 ops[4] = GEN_INT (lane);
5097 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, %3",
5101 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5104 (define_insn "neon_vld3_dup<mode>"
5105 [(set (match_operand:EI 0 "s_register_operand" "=w")
5106 (unspec:EI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5107 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5111 if (GET_MODE_NUNITS (<MODE>mode) > 1)
5113 int regno = REGNO (operands[0]);
5115 ops[0] = gen_rtx_REG (DImode, regno);
5116 ops[1] = gen_rtx_REG (DImode, regno + 2);
5117 ops[2] = gen_rtx_REG (DImode, regno + 4);
5118 ops[3] = operands[1];
5119 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[], %P1[], %P2[]}, %3", ops);
5123 return "vld1.<V_sz_elem>\t%h0, %A1";
5125 [(set (attr "neon_type")
5126 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
5127 (const_string "neon_vld3_vld4_all_lanes")
5128 (const_string "neon_vld1_1_2_regs")))])
5130 (define_expand "vec_store_lanesei<mode>"
5131 [(set (match_operand:EI 0 "neon_struct_operand")
5132 (unspec:EI [(match_operand:EI 1 "s_register_operand")
5133 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5137 (define_insn "neon_vst3<mode>"
5138 [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5139 (unspec:EI [(match_operand:EI 1 "s_register_operand" "w")
5140 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5144 if (<V_sz_elem> == 64)
5145 return "vst1.64\t%h1, %A0";
5147 return "vst3.<V_sz_elem>\t%h1, %A0";
5149 [(set (attr "neon_type")
5150 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5151 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
5152 (const_string "neon_vst2_4_regs_vst3_vst4")))])
5154 (define_expand "vec_store_lanesci<mode>"
5155 [(match_operand:CI 0 "neon_struct_operand")
5156 (match_operand:CI 1 "s_register_operand")
5157 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5160 emit_insn (gen_neon_vst3<mode> (operands[0], operands[1]));
5164 (define_expand "neon_vst3<mode>"
5165 [(match_operand:CI 0 "neon_struct_operand")
5166 (match_operand:CI 1 "s_register_operand")
5167 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5172 mem = adjust_address (operands[0], EImode, 0);
5173 emit_insn (gen_neon_vst3qa<mode> (mem, operands[1]));
5174 mem = adjust_address (mem, EImode, GET_MODE_SIZE (EImode));
5175 emit_insn (gen_neon_vst3qb<mode> (mem, operands[1]));
5179 (define_insn "neon_vst3qa<mode>"
5180 [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5181 (unspec:EI [(match_operand:CI 1 "s_register_operand" "w")
5182 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5186 int regno = REGNO (operands[1]);
5188 ops[0] = operands[0];
5189 ops[1] = gen_rtx_REG (DImode, regno);
5190 ops[2] = gen_rtx_REG (DImode, regno + 4);
5191 ops[3] = gen_rtx_REG (DImode, regno + 8);
5192 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops);
5195 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5198 (define_insn "neon_vst3qb<mode>"
5199 [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5200 (unspec:EI [(match_operand:CI 1 "s_register_operand" "w")
5201 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5205 int regno = REGNO (operands[1]);
5207 ops[0] = operands[0];
5208 ops[1] = gen_rtx_REG (DImode, regno + 2);
5209 ops[2] = gen_rtx_REG (DImode, regno + 6);
5210 ops[3] = gen_rtx_REG (DImode, regno + 10);
5211 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops);
5214 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5217 (define_insn "neon_vst3_lane<mode>"
5218 [(set (match_operand:<V_three_elem> 0 "neon_struct_operand" "=Um")
5219 (unspec:<V_three_elem>
5220 [(match_operand:EI 1 "s_register_operand" "w")
5221 (match_operand:SI 2 "immediate_operand" "i")
5222 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5226 HOST_WIDE_INT lane = INTVAL (operands[2]);
5227 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5228 int regno = REGNO (operands[1]);
5230 if (lane < 0 || lane >= max)
5231 error ("lane out of range");
5232 ops[0] = operands[0];
5233 ops[1] = gen_rtx_REG (DImode, regno);
5234 ops[2] = gen_rtx_REG (DImode, regno + 2);
5235 ops[3] = gen_rtx_REG (DImode, regno + 4);
5236 ops[4] = operands[2];
5237 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, %0",
5241 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5244 (define_insn "neon_vst3_lane<mode>"
5245 [(set (match_operand:<V_three_elem> 0 "neon_struct_operand" "=Um")
5246 (unspec:<V_three_elem>
5247 [(match_operand:CI 1 "s_register_operand" "w")
5248 (match_operand:SI 2 "immediate_operand" "i")
5249 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5253 HOST_WIDE_INT lane = INTVAL (operands[2]);
5254 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5255 int regno = REGNO (operands[1]);
5257 if (lane < 0 || lane >= max)
5258 error ("lane out of range");
5259 else if (lane >= max / 2)
5264 ops[0] = operands[0];
5265 ops[1] = gen_rtx_REG (DImode, regno);
5266 ops[2] = gen_rtx_REG (DImode, regno + 4);
5267 ops[3] = gen_rtx_REG (DImode, regno + 8);
5268 ops[4] = GEN_INT (lane);
5269 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, %0",
5273 [(set_attr "neon_type" "neon_vst3_vst4_lane")])
5275 (define_expand "vec_load_lanesoi<mode>"
5276 [(set (match_operand:OI 0 "s_register_operand")
5277 (unspec:OI [(match_operand:OI 1 "neon_struct_operand")
5278 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5282 (define_insn "neon_vld4<mode>"
5283 [(set (match_operand:OI 0 "s_register_operand" "=w")
5284 (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um")
5285 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5289 if (<V_sz_elem> == 64)
5290 return "vld1.64\t%h0, %A1";
5292 return "vld4.<V_sz_elem>\t%h0, %A1";
5294 [(set (attr "neon_type")
5295 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5296 (const_string "neon_vld1_1_2_regs")
5297 (const_string "neon_vld3_vld4")))]
5300 (define_expand "vec_load_lanesxi<mode>"
5301 [(match_operand:XI 0 "s_register_operand")
5302 (match_operand:XI 1 "neon_struct_operand")
5303 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5306 emit_insn (gen_neon_vld4<mode> (operands[0], operands[1]));
5310 (define_expand "neon_vld4<mode>"
5311 [(match_operand:XI 0 "s_register_operand")
5312 (match_operand:XI 1 "neon_struct_operand")
5313 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5318 mem = adjust_address (operands[1], OImode, 0);
5319 emit_insn (gen_neon_vld4qa<mode> (operands[0], mem));
5320 mem = adjust_address (mem, OImode, GET_MODE_SIZE (OImode));
5321 emit_insn (gen_neon_vld4qb<mode> (operands[0], mem, operands[0]));
5325 (define_insn "neon_vld4qa<mode>"
5326 [(set (match_operand:XI 0 "s_register_operand" "=w")
5327 (unspec:XI [(match_operand:OI 1 "neon_struct_operand" "Um")
5328 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5332 int regno = REGNO (operands[0]);
5334 ops[0] = gen_rtx_REG (DImode, regno);
5335 ops[1] = gen_rtx_REG (DImode, regno + 4);
5336 ops[2] = gen_rtx_REG (DImode, regno + 8);
5337 ops[3] = gen_rtx_REG (DImode, regno + 12);
5338 ops[4] = operands[1];
5339 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops);
5342 [(set_attr "neon_type" "neon_vld3_vld4")]
5345 (define_insn "neon_vld4qb<mode>"
5346 [(set (match_operand:XI 0 "s_register_operand" "=w")
5347 (unspec:XI [(match_operand:OI 1 "neon_struct_operand" "Um")
5348 (match_operand:XI 2 "s_register_operand" "0")
5349 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5353 int regno = REGNO (operands[0]);
5355 ops[0] = gen_rtx_REG (DImode, regno + 2);
5356 ops[1] = gen_rtx_REG (DImode, regno + 6);
5357 ops[2] = gen_rtx_REG (DImode, regno + 10);
5358 ops[3] = gen_rtx_REG (DImode, regno + 14);
5359 ops[4] = operands[1];
5360 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops);
5363 [(set_attr "neon_type" "neon_vld3_vld4")]
5366 (define_insn "neon_vld4_lane<mode>"
5367 [(set (match_operand:OI 0 "s_register_operand" "=w")
5368 (unspec:OI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5369 (match_operand:OI 2 "s_register_operand" "0")
5370 (match_operand:SI 3 "immediate_operand" "i")
5371 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5375 HOST_WIDE_INT lane = INTVAL (operands[3]);
5376 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5377 int regno = REGNO (operands[0]);
5379 if (lane < 0 || lane >= max)
5380 error ("lane out of range");
5381 ops[0] = gen_rtx_REG (DImode, regno);
5382 ops[1] = gen_rtx_REG (DImode, regno + 2);
5383 ops[2] = gen_rtx_REG (DImode, regno + 4);
5384 ops[3] = gen_rtx_REG (DImode, regno + 6);
5385 ops[4] = operands[1];
5386 ops[5] = operands[3];
5387 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, %A4",
5391 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5394 (define_insn "neon_vld4_lane<mode>"
5395 [(set (match_operand:XI 0 "s_register_operand" "=w")
5396 (unspec:XI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5397 (match_operand:XI 2 "s_register_operand" "0")
5398 (match_operand:SI 3 "immediate_operand" "i")
5399 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5403 HOST_WIDE_INT lane = INTVAL (operands[3]);
5404 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5405 int regno = REGNO (operands[0]);
5407 if (lane < 0 || lane >= max)
5408 error ("lane out of range");
5409 else if (lane >= max / 2)
5414 ops[0] = gen_rtx_REG (DImode, regno);
5415 ops[1] = gen_rtx_REG (DImode, regno + 4);
5416 ops[2] = gen_rtx_REG (DImode, regno + 8);
5417 ops[3] = gen_rtx_REG (DImode, regno + 12);
5418 ops[4] = operands[1];
5419 ops[5] = GEN_INT (lane);
5420 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, %A4",
5424 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5427 (define_insn "neon_vld4_dup<mode>"
5428 [(set (match_operand:OI 0 "s_register_operand" "=w")
5429 (unspec:OI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5430 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5434 if (GET_MODE_NUNITS (<MODE>mode) > 1)
5436 int regno = REGNO (operands[0]);
5438 ops[0] = gen_rtx_REG (DImode, regno);
5439 ops[1] = gen_rtx_REG (DImode, regno + 2);
5440 ops[2] = gen_rtx_REG (DImode, regno + 4);
5441 ops[3] = gen_rtx_REG (DImode, regno + 6);
5442 ops[4] = operands[1];
5443 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[], %P1[], %P2[], %P3[]}, %A4",
5448 return "vld1.<V_sz_elem>\t%h0, %A1";
5450 [(set (attr "neon_type")
5451 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
5452 (const_string "neon_vld3_vld4_all_lanes")
5453 (const_string "neon_vld1_1_2_regs")))]
5456 (define_expand "vec_store_lanesoi<mode>"
5457 [(set (match_operand:OI 0 "neon_struct_operand")
5458 (unspec:OI [(match_operand:OI 1 "s_register_operand")
5459 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5463 (define_insn "neon_vst4<mode>"
5464 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5465 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
5466 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5470 if (<V_sz_elem> == 64)
5471 return "vst1.64\t%h1, %A0";
5473 return "vst4.<V_sz_elem>\t%h1, %A0";
5475 [(set (attr "neon_type")
5476 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5477 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
5478 (const_string "neon_vst2_4_regs_vst3_vst4")))]
5481 (define_expand "vec_store_lanesxi<mode>"
5482 [(match_operand:XI 0 "neon_struct_operand")
5483 (match_operand:XI 1 "s_register_operand")
5484 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5487 emit_insn (gen_neon_vst4<mode> (operands[0], operands[1]));
5491 (define_expand "neon_vst4<mode>"
5492 [(match_operand:XI 0 "neon_struct_operand")
5493 (match_operand:XI 1 "s_register_operand")
5494 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5499 mem = adjust_address (operands[0], OImode, 0);
5500 emit_insn (gen_neon_vst4qa<mode> (mem, operands[1]));
5501 mem = adjust_address (mem, OImode, GET_MODE_SIZE (OImode));
5502 emit_insn (gen_neon_vst4qb<mode> (mem, operands[1]));
5506 (define_insn "neon_vst4qa<mode>"
5507 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5508 (unspec:OI [(match_operand:XI 1 "s_register_operand" "w")
5509 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5513 int regno = REGNO (operands[1]);
5515 ops[0] = operands[0];
5516 ops[1] = gen_rtx_REG (DImode, regno);
5517 ops[2] = gen_rtx_REG (DImode, regno + 4);
5518 ops[3] = gen_rtx_REG (DImode, regno + 8);
5519 ops[4] = gen_rtx_REG (DImode, regno + 12);
5520 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops);
5523 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5526 (define_insn "neon_vst4qb<mode>"
5527 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5528 (unspec:OI [(match_operand:XI 1 "s_register_operand" "w")
5529 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5533 int regno = REGNO (operands[1]);
5535 ops[0] = operands[0];
5536 ops[1] = gen_rtx_REG (DImode, regno + 2);
5537 ops[2] = gen_rtx_REG (DImode, regno + 6);
5538 ops[3] = gen_rtx_REG (DImode, regno + 10);
5539 ops[4] = gen_rtx_REG (DImode, regno + 14);
5540 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops);
5543 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5546 (define_insn "neon_vst4_lane<mode>"
5547 [(set (match_operand:<V_four_elem> 0 "neon_struct_operand" "=Um")
5548 (unspec:<V_four_elem>
5549 [(match_operand:OI 1 "s_register_operand" "w")
5550 (match_operand:SI 2 "immediate_operand" "i")
5551 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5555 HOST_WIDE_INT lane = INTVAL (operands[2]);
5556 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5557 int regno = REGNO (operands[1]);
5559 if (lane < 0 || lane >= max)
5560 error ("lane out of range");
5561 ops[0] = operands[0];
5562 ops[1] = gen_rtx_REG (DImode, regno);
5563 ops[2] = gen_rtx_REG (DImode, regno + 2);
5564 ops[3] = gen_rtx_REG (DImode, regno + 4);
5565 ops[4] = gen_rtx_REG (DImode, regno + 6);
5566 ops[5] = operands[2];
5567 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, %A0",
5571 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5574 (define_insn "neon_vst4_lane<mode>"
5575 [(set (match_operand:<V_four_elem> 0 "neon_struct_operand" "=Um")
5576 (unspec:<V_four_elem>
5577 [(match_operand:XI 1 "s_register_operand" "w")
5578 (match_operand:SI 2 "immediate_operand" "i")
5579 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5583 HOST_WIDE_INT lane = INTVAL (operands[2]);
5584 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5585 int regno = REGNO (operands[1]);
5587 if (lane < 0 || lane >= max)
5588 error ("lane out of range");
5589 else if (lane >= max / 2)
5594 ops[0] = operands[0];
5595 ops[1] = gen_rtx_REG (DImode, regno);
5596 ops[2] = gen_rtx_REG (DImode, regno + 4);
5597 ops[3] = gen_rtx_REG (DImode, regno + 8);
5598 ops[4] = gen_rtx_REG (DImode, regno + 12);
5599 ops[5] = GEN_INT (lane);
5600 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, %A0",
5604 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5607 (define_expand "neon_vand<mode>"
5608 [(match_operand:VDQX 0 "s_register_operand" "")
5609 (match_operand:VDQX 1 "s_register_operand" "")
5610 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5611 (match_operand:SI 3 "immediate_operand" "")]
5614 emit_insn (gen_and<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5618 (define_expand "neon_vorr<mode>"
5619 [(match_operand:VDQX 0 "s_register_operand" "")
5620 (match_operand:VDQX 1 "s_register_operand" "")
5621 (match_operand:VDQX 2 "neon_logic_op2" "")
5622 (match_operand:SI 3 "immediate_operand" "")]
5625 emit_insn (gen_ior<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5629 (define_expand "neon_veor<mode>"
5630 [(match_operand:VDQX 0 "s_register_operand" "")
5631 (match_operand:VDQX 1 "s_register_operand" "")
5632 (match_operand:VDQX 2 "s_register_operand" "")
5633 (match_operand:SI 3 "immediate_operand" "")]
5636 emit_insn (gen_xor<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5640 (define_expand "neon_vbic<mode>"
5641 [(match_operand:VDQX 0 "s_register_operand" "")
5642 (match_operand:VDQX 1 "s_register_operand" "")
5643 (match_operand:VDQX 2 "neon_logic_op2" "")
5644 (match_operand:SI 3 "immediate_operand" "")]
5647 emit_insn (gen_bic<mode>3_neon (operands[0], operands[1], operands[2]));
5651 (define_expand "neon_vorn<mode>"
5652 [(match_operand:VDQX 0 "s_register_operand" "")
5653 (match_operand:VDQX 1 "s_register_operand" "")
5654 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5655 (match_operand:SI 3 "immediate_operand" "")]
5658 emit_insn (gen_orn<mode>3_neon (operands[0], operands[1], operands[2]));
5662 (define_insn "neon_vec_unpack<US>_lo_<mode>"
5663 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5664 (SE:<V_unpack> (vec_select:<V_HALF>
5665 (match_operand:VU 1 "register_operand" "w")
5666 (match_operand:VU 2 "vect_par_constant_low" ""))))]
5667 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5668 "vmovl.<US><V_sz_elem> %q0, %e1"
5669 [(set_attr "neon_type" "neon_shift_1")]
5672 (define_insn "neon_vec_unpack<US>_hi_<mode>"
5673 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5674 (SE:<V_unpack> (vec_select:<V_HALF>
5675 (match_operand:VU 1 "register_operand" "w")
5676 (match_operand:VU 2 "vect_par_constant_high" ""))))]
5677 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5678 "vmovl.<US><V_sz_elem> %q0, %f1"
5679 [(set_attr "neon_type" "neon_shift_1")]
5682 (define_expand "vec_unpack<US>_hi_<mode>"
5683 [(match_operand:<V_unpack> 0 "register_operand" "")
5684 (SE:<V_unpack> (match_operand:VU 1 "register_operand"))]
5685 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5687 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5690 for (i = 0; i < (<V_mode_nunits>/2); i++)
5691 RTVEC_ELT (v, i) = GEN_INT ((<V_mode_nunits>/2) + i);
5693 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5694 emit_insn (gen_neon_vec_unpack<US>_hi_<mode> (operands[0],
5701 (define_expand "vec_unpack<US>_lo_<mode>"
5702 [(match_operand:<V_unpack> 0 "register_operand" "")
5703 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))]
5704 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5706 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5709 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5710 RTVEC_ELT (v, i) = GEN_INT (i);
5711 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5712 emit_insn (gen_neon_vec_unpack<US>_lo_<mode> (operands[0],
5719 (define_insn "neon_vec_<US>mult_lo_<mode>"
5720 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5721 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5722 (match_operand:VU 1 "register_operand" "w")
5723 (match_operand:VU 2 "vect_par_constant_low" "")))
5724 (SE:<V_unpack> (vec_select:<V_HALF>
5725 (match_operand:VU 3 "register_operand" "w")
5727 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5728 "vmull.<US><V_sz_elem> %q0, %e1, %e3"
5729 [(set_attr "neon_type" "neon_shift_1")]
5732 (define_expand "vec_widen_<US>mult_lo_<mode>"
5733 [(match_operand:<V_unpack> 0 "register_operand" "")
5734 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5735 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5736 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5738 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5741 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5742 RTVEC_ELT (v, i) = GEN_INT (i);
5743 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5745 emit_insn (gen_neon_vec_<US>mult_lo_<mode> (operands[0],
5753 (define_insn "neon_vec_<US>mult_hi_<mode>"
5754 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5755 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5756 (match_operand:VU 1 "register_operand" "w")
5757 (match_operand:VU 2 "vect_par_constant_high" "")))
5758 (SE:<V_unpack> (vec_select:<V_HALF>
5759 (match_operand:VU 3 "register_operand" "w")
5761 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5762 "vmull.<US><V_sz_elem> %q0, %f1, %f3"
5763 [(set_attr "neon_type" "neon_shift_1")]
5766 (define_expand "vec_widen_<US>mult_hi_<mode>"
5767 [(match_operand:<V_unpack> 0 "register_operand" "")
5768 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5769 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5770 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5772 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5775 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5776 RTVEC_ELT (v, i) = GEN_INT (<V_mode_nunits>/2 + i);
5777 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5779 emit_insn (gen_neon_vec_<US>mult_hi_<mode> (operands[0],
5788 (define_insn "neon_vec_<US>shiftl_<mode>"
5789 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5790 (SE:<V_widen> (ashift:VW (match_operand:VW 1 "register_operand" "w")
5791 (match_operand:<V_innermode> 2 "const_neon_scalar_shift_amount_operand" ""))))]
5794 return "vshll.<US><V_sz_elem> %q0, %P1, %2";
5796 [(set_attr "neon_type" "neon_shift_1")]
5799 (define_expand "vec_widen_<US>shiftl_lo_<mode>"
5800 [(match_operand:<V_unpack> 0 "register_operand" "")
5801 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5802 (match_operand:SI 2 "immediate_operand" "i")]
5803 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5805 emit_insn (gen_neon_vec_<US>shiftl_<V_half> (operands[0],
5806 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode, 0),
5812 (define_expand "vec_widen_<US>shiftl_hi_<mode>"
5813 [(match_operand:<V_unpack> 0 "register_operand" "")
5814 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5815 (match_operand:SI 2 "immediate_operand" "i")]
5816 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5818 emit_insn (gen_neon_vec_<US>shiftl_<V_half> (operands[0],
5819 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode,
5820 GET_MODE_SIZE (<V_HALF>mode)),
5826 ;; Vectorize for non-neon-quad case
5827 (define_insn "neon_unpack<US>_<mode>"
5828 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5829 (SE:<V_widen> (match_operand:VDI 1 "register_operand" "w")))]
5831 "vmovl.<US><V_sz_elem> %q0, %P1"
5832 [(set_attr "neon_type" "neon_shift_1")]
5835 (define_expand "vec_unpack<US>_lo_<mode>"
5836 [(match_operand:<V_double_width> 0 "register_operand" "")
5837 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5840 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5841 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5842 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5848 (define_expand "vec_unpack<US>_hi_<mode>"
5849 [(match_operand:<V_double_width> 0 "register_operand" "")
5850 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5853 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5854 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5855 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5861 (define_insn "neon_vec_<US>mult_<mode>"
5862 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5863 (mult:<V_widen> (SE:<V_widen>
5864 (match_operand:VDI 1 "register_operand" "w"))
5866 (match_operand:VDI 2 "register_operand" "w"))))]
5868 "vmull.<US><V_sz_elem> %q0, %P1, %P2"
5869 [(set_attr "neon_type" "neon_shift_1")]
5872 (define_expand "vec_widen_<US>mult_hi_<mode>"
5873 [(match_operand:<V_double_width> 0 "register_operand" "")
5874 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5875 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5878 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5879 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5880 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5887 (define_expand "vec_widen_<US>mult_lo_<mode>"
5888 [(match_operand:<V_double_width> 0 "register_operand" "")
5889 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5890 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5893 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5894 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5895 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5902 (define_expand "vec_widen_<US>shiftl_hi_<mode>"
5903 [(match_operand:<V_double_width> 0 "register_operand" "")
5904 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5905 (match_operand:SI 2 "immediate_operand" "i")]
5908 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5909 emit_insn (gen_neon_vec_<US>shiftl_<mode> (tmpreg, operands[1], operands[2]));
5910 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5916 (define_expand "vec_widen_<US>shiftl_lo_<mode>"
5917 [(match_operand:<V_double_width> 0 "register_operand" "")
5918 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5919 (match_operand:SI 2 "immediate_operand" "i")]
5922 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5923 emit_insn (gen_neon_vec_<US>shiftl_<mode> (tmpreg, operands[1], operands[2]));
5924 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5930 ; FIXME: These instruction patterns can't be used safely in big-endian mode
5931 ; because the ordering of vector elements in Q registers is different from what
5932 ; the semantics of the instructions require.
5934 (define_insn "vec_pack_trunc_<mode>"
5935 [(set (match_operand:<V_narrow_pack> 0 "register_operand" "=&w")
5936 (vec_concat:<V_narrow_pack>
5937 (truncate:<V_narrow>
5938 (match_operand:VN 1 "register_operand" "w"))
5939 (truncate:<V_narrow>
5940 (match_operand:VN 2 "register_operand" "w"))))]
5941 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5942 "vmovn.i<V_sz_elem>\t%e0, %q1\;vmovn.i<V_sz_elem>\t%f0, %q2"
5943 [(set_attr "neon_type" "neon_shift_1")
5944 (set_attr "length" "8")]
5947 ;; For the non-quad case.
5948 (define_insn "neon_vec_pack_trunc_<mode>"
5949 [(set (match_operand:<V_narrow> 0 "register_operand" "=w")
5950 (truncate:<V_narrow> (match_operand:VN 1 "register_operand" "w")))]
5951 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5952 "vmovn.i<V_sz_elem>\t%P0, %q1"
5953 [(set_attr "neon_type" "neon_shift_1")]
5956 (define_expand "vec_pack_trunc_<mode>"
5957 [(match_operand:<V_narrow_pack> 0 "register_operand" "")
5958 (match_operand:VSHFT 1 "register_operand" "")
5959 (match_operand:VSHFT 2 "register_operand")]
5960 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5962 rtx tempreg = gen_reg_rtx (<V_DOUBLE>mode);
5964 emit_insn (gen_move_lo_quad_<V_double> (tempreg, operands[1]));
5965 emit_insn (gen_move_hi_quad_<V_double> (tempreg, operands[2]));
5966 emit_insn (gen_neon_vec_pack_trunc_<V_double> (operands[0], tempreg));
5970 (define_insn "neon_vabd<mode>_2"
5971 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
5972 (abs:VDQ (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
5973 (match_operand:VDQ 2 "s_register_operand" "w"))))]
5974 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
5975 "vabd.<V_s_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2"
5976 [(set (attr "neon_type")
5977 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
5978 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
5979 (const_string "neon_fp_vadd_ddd_vabs_dd")
5980 (const_string "neon_fp_vadd_qqq_vabs_qq"))
5981 (const_string "neon_int_5")))]
5984 (define_insn "neon_vabd<mode>_3"
5985 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
5986 (abs:VDQ (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
5987 (match_operand:VDQ 2 "s_register_operand" "w")]
5989 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
5990 "vabd.<V_if_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2"
5991 [(set (attr "neon_type")
5992 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
5993 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
5994 (const_string "neon_fp_vadd_ddd_vabs_dd")
5995 (const_string "neon_fp_vadd_qqq_vabs_qq"))
5996 (const_string "neon_int_5")))]
5999 ;; Copy from core-to-neon regs, then extend, not vice-versa
6002 [(set (match_operand:DI 0 "s_register_operand" "")
6003 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
6004 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6005 [(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1)))
6006 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 32)))]
6008 operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0]));
6012 [(set (match_operand:DI 0 "s_register_operand" "")
6013 (sign_extend:DI (match_operand:HI 1 "s_register_operand" "")))]
6014 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6015 [(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1)))
6016 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
6018 operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0]));
6022 [(set (match_operand:DI 0 "s_register_operand" "")
6023 (sign_extend:DI (match_operand:QI 1 "s_register_operand" "")))]
6024 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6025 [(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1)))
6026 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
6028 operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0]));
6032 [(set (match_operand:DI 0 "s_register_operand" "")
6033 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
6034 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6035 [(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1)))
6036 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 32)))]
6038 operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0]));
6042 [(set (match_operand:DI 0 "s_register_operand" "")
6043 (zero_extend:DI (match_operand:HI 1 "s_register_operand" "")))]
6044 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6045 [(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1)))
6046 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
6048 operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0]));
6052 [(set (match_operand:DI 0 "s_register_operand" "")
6053 (zero_extend:DI (match_operand:QI 1 "s_register_operand" "")))]
6054 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6055 [(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1)))
6056 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
6058 operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0]));