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 && unaligned_access"
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 && unaligned_access"
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 && unaligned_access"
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 && unaligned_access"
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 && unaligned_access"
286 "vld1.<V_sz_elem>\t{%q0}, %A1"
287 [(set_attr "neon_type" "neon_vld1_1_2_regs")])
289 (define_insn "vec_set<mode>_internal"
290 [(set (match_operand:VD 0 "s_register_operand" "=w,w")
293 (match_operand:<V_elem> 1 "nonimmediate_operand" "Um,r"))
294 (match_operand:VD 3 "s_register_operand" "0,0")
295 (match_operand:SI 2 "immediate_operand" "i,i")))]
298 int elt = ffs ((int) INTVAL (operands[2])) - 1;
299 if (BYTES_BIG_ENDIAN)
300 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
301 operands[2] = GEN_INT (elt);
303 if (which_alternative == 0)
304 return "vld1.<V_sz_elem>\t{%P0[%c2]}, %A1";
306 return "vmov.<V_sz_elem>\t%P0[%c2], %1";
308 [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")])
310 (define_insn "vec_set<mode>_internal"
311 [(set (match_operand:VQ 0 "s_register_operand" "=w,w")
314 (match_operand:<V_elem> 1 "nonimmediate_operand" "Um,r"))
315 (match_operand:VQ 3 "s_register_operand" "0,0")
316 (match_operand:SI 2 "immediate_operand" "i,i")))]
319 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
320 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
321 int elt = elem % half_elts;
322 int hi = (elem / half_elts) * 2;
323 int regno = REGNO (operands[0]);
325 if (BYTES_BIG_ENDIAN)
326 elt = half_elts - 1 - elt;
328 operands[0] = gen_rtx_REG (<V_HALF>mode, regno + hi);
329 operands[2] = GEN_INT (elt);
331 if (which_alternative == 0)
332 return "vld1.<V_sz_elem>\t{%P0[%c2]}, %A1";
334 return "vmov.<V_sz_elem>\t%P0[%c2], %1";
336 [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")]
339 (define_insn "vec_setv2di_internal"
340 [(set (match_operand:V2DI 0 "s_register_operand" "=w,w")
343 (match_operand:DI 1 "nonimmediate_operand" "Um,r"))
344 (match_operand:V2DI 3 "s_register_operand" "0,0")
345 (match_operand:SI 2 "immediate_operand" "i,i")))]
348 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
349 int regno = REGNO (operands[0]) + 2 * elem;
351 operands[0] = gen_rtx_REG (DImode, regno);
353 if (which_alternative == 0)
354 return "vld1.64\t%P0, %A1";
356 return "vmov\t%P0, %Q1, %R1";
358 [(set_attr "neon_type" "neon_vld1_1_2_regs,neon_mcr_2_mcrr")]
361 (define_expand "vec_set<mode>"
362 [(match_operand:VDQ 0 "s_register_operand" "")
363 (match_operand:<V_elem> 1 "s_register_operand" "")
364 (match_operand:SI 2 "immediate_operand" "")]
367 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
368 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
369 GEN_INT (elem), operands[0]));
373 (define_insn "vec_extract<mode>"
374 [(set (match_operand:<V_elem> 0 "nonimmediate_operand" "=Um,r")
376 (match_operand:VD 1 "s_register_operand" "w,w")
377 (parallel [(match_operand:SI 2 "immediate_operand" "i,i")])))]
380 if (BYTES_BIG_ENDIAN)
382 int elt = INTVAL (operands[2]);
383 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
384 operands[2] = GEN_INT (elt);
387 if (which_alternative == 0)
388 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
390 return "vmov.<V_uf_sclr>\t%0, %P1[%c2]";
392 [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_bp_simple")]
395 (define_insn "vec_extract<mode>"
396 [(set (match_operand:<V_elem> 0 "nonimmediate_operand" "=Um,r")
398 (match_operand:VQ 1 "s_register_operand" "w,w")
399 (parallel [(match_operand:SI 2 "immediate_operand" "i,i")])))]
402 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
403 int elt = INTVAL (operands[2]) % half_elts;
404 int hi = (INTVAL (operands[2]) / half_elts) * 2;
405 int regno = REGNO (operands[1]);
407 if (BYTES_BIG_ENDIAN)
408 elt = half_elts - 1 - elt;
410 operands[1] = gen_rtx_REG (<V_HALF>mode, regno + hi);
411 operands[2] = GEN_INT (elt);
413 if (which_alternative == 0)
414 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
416 return "vmov.<V_uf_sclr>\t%0, %P1[%c2]";
418 [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_bp_simple")]
421 (define_insn "vec_extractv2di"
422 [(set (match_operand:DI 0 "nonimmediate_operand" "=Um,r")
424 (match_operand:V2DI 1 "s_register_operand" "w,w")
425 (parallel [(match_operand:SI 2 "immediate_operand" "i,i")])))]
428 int regno = REGNO (operands[1]) + 2 * INTVAL (operands[2]);
430 operands[1] = gen_rtx_REG (DImode, regno);
432 if (which_alternative == 0)
433 return "vst1.64\t{%P1}, %A0 @ v2di";
435 return "vmov\t%Q0, %R0, %P1 @ v2di";
437 [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_int_1")]
440 (define_expand "vec_init<mode>"
441 [(match_operand:VDQ 0 "s_register_operand" "")
442 (match_operand 1 "" "")]
445 neon_expand_vector_init (operands[0], operands[1]);
449 ;; Doubleword and quadword arithmetic.
451 ;; NOTE: some other instructions also support 64-bit integer
452 ;; element size, which we could potentially use for "long long" operations.
454 (define_insn "*add<mode>3_neon"
455 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
456 (plus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
457 (match_operand:VDQ 2 "s_register_operand" "w")))]
458 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
459 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
460 [(set (attr "neon_type")
461 (if_then_else (match_test "<Is_float_mode>")
462 (if_then_else (match_test "<Is_d_reg>")
463 (const_string "neon_fp_vadd_ddd_vabs_dd")
464 (const_string "neon_fp_vadd_qqq_vabs_qq"))
465 (const_string "neon_int_1")))]
468 (define_insn "adddi3_neon"
469 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w,?&r,?&r,?&r")
470 (plus:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,w,r,0,r")
471 (match_operand:DI 2 "arm_adddi_operand" "w,r,0,w,r,Dd,Dd")))
472 (clobber (reg:CC CC_REGNUM))]
475 switch (which_alternative)
477 case 0: /* fall through */
478 case 3: return "vadd.i64\t%P0, %P1, %P2";
484 default: gcc_unreachable ();
487 [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1,*,*,*")
488 (set_attr "conds" "*,clob,clob,*,clob,clob,clob")
489 (set_attr "length" "*,8,8,*,8,8,8")
490 (set_attr "arch" "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 use_zero_form = 0;
1736 int swap_bsl_operands = 0;
1737 rtx mask = gen_reg_rtx (<V_cmp_result>mode);
1738 rtx tmp = gen_reg_rtx (<V_cmp_result>mode);
1740 rtx (*base_comparison) (rtx, rtx, rtx, rtx);
1741 rtx (*complimentary_comparison) (rtx, rtx, rtx, rtx);
1743 switch (GET_CODE (operands[3]))
1750 if (operands[5] == CONST0_RTX (<MODE>mode))
1757 if (!REG_P (operands[5]))
1758 operands[5] = force_reg (<MODE>mode, operands[5]);
1761 switch (GET_CODE (operands[3]))
1771 base_comparison = gen_neon_vcge<mode>;
1772 complimentary_comparison = gen_neon_vcgt<mode>;
1780 base_comparison = gen_neon_vcgt<mode>;
1781 complimentary_comparison = gen_neon_vcge<mode>;
1786 base_comparison = gen_neon_vceq<mode>;
1787 complimentary_comparison = gen_neon_vceq<mode>;
1793 switch (GET_CODE (operands[3]))
1800 /* The easy case. Here we emit one of vcge, vcgt or vceq.
1801 As a LT b <=> b GE a && a LE b <=> b GT a. Our transformations are:
1807 Note that there also exist direct comparison against 0 forms,
1808 so catch those as a special case. */
1812 switch (GET_CODE (operands[3]))
1815 base_comparison = gen_neon_vclt<mode>;
1818 base_comparison = gen_neon_vcle<mode>;
1821 /* Do nothing, other zero form cases already have the correct
1828 emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx));
1830 emit_insn (complimentary_comparison (mask, operands[5], operands[4], magic_rtx));
1837 /* Vector compare returns false for lanes which are unordered, so if we use
1838 the inverse of the comparison we actually want to emit, then
1839 swap the operands to BSL, we will end up with the correct result.
1840 Note that a NE NaN and NaN NE b are true for all a, b.
1842 Our transformations are:
1847 a NE b -> !(a EQ b) */
1850 emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx));
1852 emit_insn (complimentary_comparison (mask, operands[5], operands[4], magic_rtx));
1854 swap_bsl_operands = 1;
1857 /* We check (a > b || b > a). combining these comparisons give us
1858 true iff !(a != b && a ORDERED b), swapping the operands to BSL
1859 will then give us (a == b || a UNORDERED b) as intended. */
1861 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5], magic_rtx));
1862 emit_insn (gen_neon_vcgt<mode> (tmp, operands[5], operands[4], magic_rtx));
1863 emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
1864 swap_bsl_operands = 1;
1867 /* Operands are ORDERED iff (a > b || b >= a).
1868 Swapping the operands to BSL will give the UNORDERED case. */
1869 swap_bsl_operands = 1;
1872 emit_insn (gen_neon_vcgt<mode> (tmp, operands[4], operands[5], magic_rtx));
1873 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4], magic_rtx));
1874 emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
1880 if (swap_bsl_operands)
1881 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1884 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1889 (define_expand "vcondu<mode><mode>"
1890 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1892 (match_operator 3 "arm_comparison_operator"
1893 [(match_operand:VDQIW 4 "s_register_operand" "")
1894 (match_operand:VDQIW 5 "s_register_operand" "")])
1895 (match_operand:VDQIW 1 "s_register_operand" "")
1896 (match_operand:VDQIW 2 "s_register_operand" "")))]
1900 int inverse = 0, immediate_zero = 0;
1902 mask = gen_reg_rtx (<V_cmp_result>mode);
1904 if (operands[5] == CONST0_RTX (<MODE>mode))
1906 else if (!REG_P (operands[5]))
1907 operands[5] = force_reg (<MODE>mode, operands[5]);
1909 switch (GET_CODE (operands[3]))
1912 emit_insn (gen_neon_vcge<mode> (mask, operands[4], operands[5],
1917 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5],
1922 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1928 emit_insn (gen_neon_vcle<mode> (mask, operands[4], operands[5],
1931 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4],
1937 emit_insn (gen_neon_vclt<mode> (mask, operands[4], operands[5],
1940 emit_insn (gen_neon_vcgt<mode> (mask, operands[5], operands[4],
1945 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1955 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1958 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1964 ;; Patterns for builtins.
1966 ; good for plain vadd, vaddq.
1968 (define_expand "neon_vadd<mode>"
1969 [(match_operand:VDQX 0 "s_register_operand" "=w")
1970 (match_operand:VDQX 1 "s_register_operand" "w")
1971 (match_operand:VDQX 2 "s_register_operand" "w")
1972 (match_operand:SI 3 "immediate_operand" "i")]
1975 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1976 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[2]));
1978 emit_insn (gen_neon_vadd<mode>_unspec (operands[0], operands[1],
1983 ; Note that NEON operations don't support the full IEEE 754 standard: in
1984 ; particular, denormal values are flushed to zero. This means that GCC cannot
1985 ; use those instructions for autovectorization, etc. unless
1986 ; -funsafe-math-optimizations is in effect (in which case flush-to-zero
1987 ; behaviour is permissible). Intrinsic operations (provided by the arm_neon.h
1988 ; header) must work in either case: if -funsafe-math-optimizations is given,
1989 ; intrinsics expand to "canonical" RTL where possible, otherwise intrinsics
1990 ; expand to unspecs (which may potentially limit the extent to which they might
1991 ; be optimized by generic code).
1993 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1995 (define_insn "neon_vadd<mode>_unspec"
1996 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1997 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1998 (match_operand:VDQX 2 "s_register_operand" "w")]
2001 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2002 [(set (attr "neon_type")
2003 (if_then_else (match_test "<Is_float_mode>")
2004 (if_then_else (match_test "<Is_d_reg>")
2005 (const_string "neon_fp_vadd_ddd_vabs_dd")
2006 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2007 (const_string "neon_int_1")))]
2010 ; operand 3 represents in bits:
2011 ; bit 0: signed (vs unsigned).
2012 ; bit 1: rounding (vs none).
2014 (define_insn "neon_vaddl<mode>"
2015 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2016 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
2017 (match_operand:VDI 2 "s_register_operand" "w")
2018 (match_operand:SI 3 "immediate_operand" "i")]
2021 "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2022 [(set_attr "neon_type" "neon_int_3")]
2025 (define_insn "neon_vaddw<mode>"
2026 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2027 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
2028 (match_operand:VDI 2 "s_register_operand" "w")
2029 (match_operand:SI 3 "immediate_operand" "i")]
2032 "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
2033 [(set_attr "neon_type" "neon_int_2")]
2038 (define_insn "neon_vhadd<mode>"
2039 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2040 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2041 (match_operand:VDQIW 2 "s_register_operand" "w")
2042 (match_operand:SI 3 "immediate_operand" "i")]
2045 "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2046 [(set_attr "neon_type" "neon_int_4")]
2049 (define_insn "neon_vqadd<mode>"
2050 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2051 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2052 (match_operand:VDQIX 2 "s_register_operand" "w")
2053 (match_operand:SI 3 "immediate_operand" "i")]
2056 "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2057 [(set_attr "neon_type" "neon_int_4")]
2060 (define_insn "neon_vaddhn<mode>"
2061 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2062 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2063 (match_operand:VN 2 "s_register_operand" "w")
2064 (match_operand:SI 3 "immediate_operand" "i")]
2067 "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2"
2068 [(set_attr "neon_type" "neon_int_4")]
2071 ;; We cannot replace this unspec with mul<mode>3 because of the odd
2072 ;; polynomial multiplication case that can specified by operand 3.
2073 (define_insn "neon_vmul<mode>"
2074 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2075 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2076 (match_operand:VDQW 2 "s_register_operand" "w")
2077 (match_operand:SI 3 "immediate_operand" "i")]
2080 "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2081 [(set (attr "neon_type")
2082 (if_then_else (match_test "<Is_float_mode>")
2083 (if_then_else (match_test "<Is_d_reg>")
2084 (const_string "neon_fp_vadd_ddd_vabs_dd")
2085 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2086 (if_then_else (match_test "<Is_d_reg>")
2088 (match_test "<Scalar_mul_8_16>")
2089 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2090 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
2091 (if_then_else (match_test "<Scalar_mul_8_16>")
2092 (const_string "neon_mul_qqq_8_16_32_ddd_32")
2093 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
2096 (define_expand "neon_vmla<mode>"
2097 [(match_operand:VDQW 0 "s_register_operand" "=w")
2098 (match_operand:VDQW 1 "s_register_operand" "0")
2099 (match_operand:VDQW 2 "s_register_operand" "w")
2100 (match_operand:VDQW 3 "s_register_operand" "w")
2101 (match_operand:SI 4 "immediate_operand" "i")]
2104 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2105 emit_insn (gen_mul<mode>3add<mode>_neon (operands[0], operands[1],
2106 operands[2], operands[3]));
2108 emit_insn (gen_neon_vmla<mode>_unspec (operands[0], operands[1],
2109 operands[2], operands[3]));
2113 (define_expand "neon_vfma<VCVTF:mode>"
2114 [(match_operand:VCVTF 0 "s_register_operand")
2115 (match_operand:VCVTF 1 "s_register_operand")
2116 (match_operand:VCVTF 2 "s_register_operand")
2117 (match_operand:VCVTF 3 "s_register_operand")
2118 (match_operand:SI 4 "immediate_operand")]
2119 "TARGET_NEON && TARGET_FMA"
2121 emit_insn (gen_fma<mode>4_intrinsic (operands[0], operands[2], operands[3],
2126 (define_expand "neon_vfms<VCVTF:mode>"
2127 [(match_operand:VCVTF 0 "s_register_operand")
2128 (match_operand:VCVTF 1 "s_register_operand")
2129 (match_operand:VCVTF 2 "s_register_operand")
2130 (match_operand:VCVTF 3 "s_register_operand")
2131 (match_operand:SI 4 "immediate_operand")]
2132 "TARGET_NEON && TARGET_FMA"
2134 emit_insn (gen_fmsub<mode>4_intrinsic (operands[0], operands[2], operands[3],
2139 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2141 (define_insn "neon_vmla<mode>_unspec"
2142 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
2143 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
2144 (match_operand:VDQ 2 "s_register_operand" "w")
2145 (match_operand:VDQ 3 "s_register_operand" "w")]
2148 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2149 [(set (attr "neon_type")
2150 (if_then_else (match_test "<Is_float_mode>")
2151 (if_then_else (match_test "<Is_d_reg>")
2152 (const_string "neon_fp_vmla_ddd")
2153 (const_string "neon_fp_vmla_qqq"))
2154 (if_then_else (match_test "<Is_d_reg>")
2156 (match_test "<Scalar_mul_8_16>")
2157 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2158 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
2159 (if_then_else (match_test "<Scalar_mul_8_16>")
2160 (const_string "neon_mla_qqq_8_16")
2161 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
2164 (define_insn "neon_vmlal<mode>"
2165 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2166 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2167 (match_operand:VW 2 "s_register_operand" "w")
2168 (match_operand:VW 3 "s_register_operand" "w")
2169 (match_operand:SI 4 "immediate_operand" "i")]
2172 "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2173 [(set (attr "neon_type")
2174 (if_then_else (match_test "<Scalar_mul_8_16>")
2175 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2176 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2179 (define_expand "neon_vmls<mode>"
2180 [(match_operand:VDQW 0 "s_register_operand" "=w")
2181 (match_operand:VDQW 1 "s_register_operand" "0")
2182 (match_operand:VDQW 2 "s_register_operand" "w")
2183 (match_operand:VDQW 3 "s_register_operand" "w")
2184 (match_operand:SI 4 "immediate_operand" "i")]
2187 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2188 emit_insn (gen_mul<mode>3neg<mode>add<mode>_neon (operands[0],
2189 operands[1], operands[2], operands[3]));
2191 emit_insn (gen_neon_vmls<mode>_unspec (operands[0], operands[1],
2192 operands[2], operands[3]));
2196 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2198 (define_insn "neon_vmls<mode>_unspec"
2199 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
2200 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
2201 (match_operand:VDQ 2 "s_register_operand" "w")
2202 (match_operand:VDQ 3 "s_register_operand" "w")]
2205 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2206 [(set (attr "neon_type")
2207 (if_then_else (match_test "<Is_float_mode>")
2208 (if_then_else (match_test "<Is_d_reg>")
2209 (const_string "neon_fp_vmla_ddd")
2210 (const_string "neon_fp_vmla_qqq"))
2211 (if_then_else (match_test "<Is_d_reg>")
2213 (match_test "<Scalar_mul_8_16>")
2214 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2215 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
2217 (match_test "<Scalar_mul_8_16>")
2218 (const_string "neon_mla_qqq_8_16")
2219 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
2222 (define_insn "neon_vmlsl<mode>"
2223 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2224 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2225 (match_operand:VW 2 "s_register_operand" "w")
2226 (match_operand:VW 3 "s_register_operand" "w")
2227 (match_operand:SI 4 "immediate_operand" "i")]
2230 "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2231 [(set (attr "neon_type")
2232 (if_then_else (match_test "<Scalar_mul_8_16>")
2233 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2234 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2237 (define_insn "neon_vqdmulh<mode>"
2238 [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
2239 (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
2240 (match_operand:VMDQI 2 "s_register_operand" "w")
2241 (match_operand:SI 3 "immediate_operand" "i")]
2244 "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2245 [(set (attr "neon_type")
2246 (if_then_else (match_test "<Is_d_reg>")
2247 (if_then_else (match_test "<Scalar_mul_8_16>")
2248 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2249 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
2250 (if_then_else (match_test "<Scalar_mul_8_16>")
2251 (const_string "neon_mul_qqq_8_16_32_ddd_32")
2252 (const_string "neon_mul_qqq_8_16_32_ddd_32"))))]
2255 (define_insn "neon_vqdmlal<mode>"
2256 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2257 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2258 (match_operand:VMDI 2 "s_register_operand" "w")
2259 (match_operand:VMDI 3 "s_register_operand" "w")
2260 (match_operand:SI 4 "immediate_operand" "i")]
2263 "vqdmlal.<V_s_elem>\t%q0, %P2, %P3"
2264 [(set (attr "neon_type")
2265 (if_then_else (match_test "<Scalar_mul_8_16>")
2266 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2267 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2270 (define_insn "neon_vqdmlsl<mode>"
2271 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2272 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2273 (match_operand:VMDI 2 "s_register_operand" "w")
2274 (match_operand:VMDI 3 "s_register_operand" "w")
2275 (match_operand:SI 4 "immediate_operand" "i")]
2278 "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3"
2279 [(set (attr "neon_type")
2280 (if_then_else (match_test "<Scalar_mul_8_16>")
2281 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2282 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2285 (define_insn "neon_vmull<mode>"
2286 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2287 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2288 (match_operand:VW 2 "s_register_operand" "w")
2289 (match_operand:SI 3 "immediate_operand" "i")]
2292 "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2293 [(set (attr "neon_type")
2294 (if_then_else (match_test "<Scalar_mul_8_16>")
2295 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2296 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2299 (define_insn "neon_vqdmull<mode>"
2300 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2301 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
2302 (match_operand:VMDI 2 "s_register_operand" "w")
2303 (match_operand:SI 3 "immediate_operand" "i")]
2306 "vqdmull.<V_s_elem>\t%q0, %P1, %P2"
2307 [(set (attr "neon_type")
2308 (if_then_else (match_test "<Scalar_mul_8_16>")
2309 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2310 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2313 (define_expand "neon_vsub<mode>"
2314 [(match_operand:VDQX 0 "s_register_operand" "=w")
2315 (match_operand:VDQX 1 "s_register_operand" "w")
2316 (match_operand:VDQX 2 "s_register_operand" "w")
2317 (match_operand:SI 3 "immediate_operand" "i")]
2320 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2321 emit_insn (gen_sub<mode>3 (operands[0], operands[1], operands[2]));
2323 emit_insn (gen_neon_vsub<mode>_unspec (operands[0], operands[1],
2328 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2330 (define_insn "neon_vsub<mode>_unspec"
2331 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
2332 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
2333 (match_operand:VDQX 2 "s_register_operand" "w")]
2336 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2337 [(set (attr "neon_type")
2338 (if_then_else (match_test "<Is_float_mode>")
2339 (if_then_else (match_test "<Is_d_reg>")
2340 (const_string "neon_fp_vadd_ddd_vabs_dd")
2341 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2342 (const_string "neon_int_2")))]
2345 (define_insn "neon_vsubl<mode>"
2346 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2347 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
2348 (match_operand:VDI 2 "s_register_operand" "w")
2349 (match_operand:SI 3 "immediate_operand" "i")]
2352 "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2353 [(set_attr "neon_type" "neon_int_2")]
2356 (define_insn "neon_vsubw<mode>"
2357 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2358 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
2359 (match_operand:VDI 2 "s_register_operand" "w")
2360 (match_operand:SI 3 "immediate_operand" "i")]
2363 "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
2364 [(set_attr "neon_type" "neon_int_2")]
2367 (define_insn "neon_vqsub<mode>"
2368 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2369 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2370 (match_operand:VDQIX 2 "s_register_operand" "w")
2371 (match_operand:SI 3 "immediate_operand" "i")]
2374 "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2375 [(set_attr "neon_type" "neon_int_5")]
2378 (define_insn "neon_vhsub<mode>"
2379 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2380 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2381 (match_operand:VDQIW 2 "s_register_operand" "w")
2382 (match_operand:SI 3 "immediate_operand" "i")]
2385 "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2386 [(set_attr "neon_type" "neon_int_5")]
2389 (define_insn "neon_vsubhn<mode>"
2390 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2391 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2392 (match_operand:VN 2 "s_register_operand" "w")
2393 (match_operand:SI 3 "immediate_operand" "i")]
2396 "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2"
2397 [(set_attr "neon_type" "neon_int_4")]
2400 (define_insn "neon_vceq<mode>"
2401 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2402 (unspec:<V_cmp_result>
2403 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2404 (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2405 (match_operand:SI 3 "immediate_operand" "i,i")]
2409 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2410 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, #0"
2411 [(set (attr "neon_type")
2412 (if_then_else (match_test "<Is_float_mode>")
2413 (if_then_else (match_test "<Is_d_reg>")
2414 (const_string "neon_fp_vadd_ddd_vabs_dd")
2415 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2416 (const_string "neon_int_5")))]
2419 (define_insn "neon_vcge<mode>"
2420 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2421 (unspec:<V_cmp_result>
2422 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2423 (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2424 (match_operand:SI 3 "immediate_operand" "i,i")]
2428 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2429 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2430 [(set (attr "neon_type")
2431 (if_then_else (match_test "<Is_float_mode>")
2432 (if_then_else (match_test "<Is_d_reg>")
2433 (const_string "neon_fp_vadd_ddd_vabs_dd")
2434 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2435 (const_string "neon_int_5")))]
2438 (define_insn "neon_vcgeu<mode>"
2439 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2440 (unspec:<V_cmp_result>
2441 [(match_operand:VDQIW 1 "s_register_operand" "w")
2442 (match_operand:VDQIW 2 "s_register_operand" "w")
2443 (match_operand:SI 3 "immediate_operand" "i")]
2446 "vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2447 [(set_attr "neon_type" "neon_int_5")]
2450 (define_insn "neon_vcgt<mode>"
2451 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2452 (unspec:<V_cmp_result>
2453 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2454 (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2455 (match_operand:SI 3 "immediate_operand" "i,i")]
2459 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2460 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2461 [(set (attr "neon_type")
2462 (if_then_else (match_test "<Is_float_mode>")
2463 (if_then_else (match_test "<Is_d_reg>")
2464 (const_string "neon_fp_vadd_ddd_vabs_dd")
2465 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2466 (const_string "neon_int_5")))]
2469 (define_insn "neon_vcgtu<mode>"
2470 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2471 (unspec:<V_cmp_result>
2472 [(match_operand:VDQIW 1 "s_register_operand" "w")
2473 (match_operand:VDQIW 2 "s_register_operand" "w")
2474 (match_operand:SI 3 "immediate_operand" "i")]
2477 "vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2478 [(set_attr "neon_type" "neon_int_5")]
2481 ;; VCLE and VCLT only support comparisons with immediate zero (register
2482 ;; variants are VCGE and VCGT with operands reversed).
2484 (define_insn "neon_vcle<mode>"
2485 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2486 (unspec:<V_cmp_result>
2487 [(match_operand:VDQW 1 "s_register_operand" "w")
2488 (match_operand:VDQW 2 "zero_operand" "Dz")
2489 (match_operand:SI 3 "immediate_operand" "i")]
2492 "vcle.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2493 [(set (attr "neon_type")
2494 (if_then_else (match_test "<Is_float_mode>")
2495 (if_then_else (match_test "<Is_d_reg>")
2496 (const_string "neon_fp_vadd_ddd_vabs_dd")
2497 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2498 (const_string "neon_int_5")))]
2501 (define_insn "neon_vclt<mode>"
2502 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2503 (unspec:<V_cmp_result>
2504 [(match_operand:VDQW 1 "s_register_operand" "w")
2505 (match_operand:VDQW 2 "zero_operand" "Dz")
2506 (match_operand:SI 3 "immediate_operand" "i")]
2509 "vclt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2510 [(set (attr "neon_type")
2511 (if_then_else (match_test "<Is_float_mode>")
2512 (if_then_else (match_test "<Is_d_reg>")
2513 (const_string "neon_fp_vadd_ddd_vabs_dd")
2514 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2515 (const_string "neon_int_5")))]
2518 (define_insn "neon_vcage<mode>"
2519 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2520 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2521 (match_operand:VCVTF 2 "s_register_operand" "w")
2522 (match_operand:SI 3 "immediate_operand" "i")]
2525 "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2526 [(set (attr "neon_type")
2527 (if_then_else (match_test "<Is_d_reg>")
2528 (const_string "neon_fp_vadd_ddd_vabs_dd")
2529 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2532 (define_insn "neon_vcagt<mode>"
2533 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2534 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2535 (match_operand:VCVTF 2 "s_register_operand" "w")
2536 (match_operand:SI 3 "immediate_operand" "i")]
2539 "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2540 [(set (attr "neon_type")
2541 (if_then_else (match_test "<Is_d_reg>")
2542 (const_string "neon_fp_vadd_ddd_vabs_dd")
2543 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2546 (define_insn "neon_vtst<mode>"
2547 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2548 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2549 (match_operand:VDQIW 2 "s_register_operand" "w")
2550 (match_operand:SI 3 "immediate_operand" "i")]
2553 "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2554 [(set_attr "neon_type" "neon_int_4")]
2557 (define_insn "neon_vabd<mode>"
2558 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2559 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2560 (match_operand:VDQW 2 "s_register_operand" "w")
2561 (match_operand:SI 3 "immediate_operand" "i")]
2564 "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2565 [(set (attr "neon_type")
2566 (if_then_else (match_test "<Is_float_mode>")
2567 (if_then_else (match_test "<Is_d_reg>")
2568 (const_string "neon_fp_vadd_ddd_vabs_dd")
2569 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2570 (const_string "neon_int_5")))]
2573 (define_insn "neon_vabdl<mode>"
2574 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2575 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2576 (match_operand:VW 2 "s_register_operand" "w")
2577 (match_operand:SI 3 "immediate_operand" "i")]
2580 "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2581 [(set_attr "neon_type" "neon_int_5")]
2584 (define_insn "neon_vaba<mode>"
2585 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2586 (plus:VDQIW (unspec:VDQIW [(match_operand:VDQIW 2 "s_register_operand" "w")
2587 (match_operand:VDQIW 3 "s_register_operand" "w")
2588 (match_operand:SI 4 "immediate_operand" "i")]
2590 (match_operand:VDQIW 1 "s_register_operand" "0")))]
2592 "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2593 [(set (attr "neon_type")
2594 (if_then_else (match_test "<Is_d_reg>")
2595 (const_string "neon_vaba") (const_string "neon_vaba_qqq")))]
2598 (define_insn "neon_vabal<mode>"
2599 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2600 (plus:<V_widen> (unspec:<V_widen> [(match_operand:VW 2 "s_register_operand" "w")
2601 (match_operand:VW 3 "s_register_operand" "w")
2602 (match_operand:SI 4 "immediate_operand" "i")]
2604 (match_operand:<V_widen> 1 "s_register_operand" "0")))]
2606 "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2607 [(set_attr "neon_type" "neon_vaba")]
2610 (define_insn "neon_vmax<mode>"
2611 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2612 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2613 (match_operand:VDQW 2 "s_register_operand" "w")
2614 (match_operand:SI 3 "immediate_operand" "i")]
2617 "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2618 [(set (attr "neon_type")
2619 (if_then_else (match_test "<Is_float_mode>")
2620 (if_then_else (match_test "<Is_d_reg>")
2621 (const_string "neon_fp_vadd_ddd_vabs_dd")
2622 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2623 (const_string "neon_int_5")))]
2626 (define_insn "neon_vmin<mode>"
2627 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2628 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2629 (match_operand:VDQW 2 "s_register_operand" "w")
2630 (match_operand:SI 3 "immediate_operand" "i")]
2633 "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2634 [(set (attr "neon_type")
2635 (if_then_else (match_test "<Is_float_mode>")
2636 (if_then_else (match_test "<Is_d_reg>")
2637 (const_string "neon_fp_vadd_ddd_vabs_dd")
2638 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2639 (const_string "neon_int_5")))]
2642 (define_expand "neon_vpadd<mode>"
2643 [(match_operand:VD 0 "s_register_operand" "=w")
2644 (match_operand:VD 1 "s_register_operand" "w")
2645 (match_operand:VD 2 "s_register_operand" "w")
2646 (match_operand:SI 3 "immediate_operand" "i")]
2649 emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1],
2654 (define_insn "neon_vpaddl<mode>"
2655 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2656 (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")
2657 (match_operand:SI 2 "immediate_operand" "i")]
2660 "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2661 ;; Assume this schedules like vaddl.
2662 [(set_attr "neon_type" "neon_int_3")]
2665 (define_insn "neon_vpadal<mode>"
2666 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2667 (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0")
2668 (match_operand:VDQIW 2 "s_register_operand" "w")
2669 (match_operand:SI 3 "immediate_operand" "i")]
2672 "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
2673 ;; Assume this schedules like vpadd.
2674 [(set_attr "neon_type" "neon_int_1")]
2677 (define_insn "neon_vpmax<mode>"
2678 [(set (match_operand:VD 0 "s_register_operand" "=w")
2679 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2680 (match_operand:VD 2 "s_register_operand" "w")
2681 (match_operand:SI 3 "immediate_operand" "i")]
2684 "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2685 ;; Assume this schedules like vmax.
2686 [(set (attr "neon_type")
2687 (if_then_else (match_test "<Is_float_mode>")
2688 (const_string "neon_fp_vadd_ddd_vabs_dd")
2689 (const_string "neon_int_5")))]
2692 (define_insn "neon_vpmin<mode>"
2693 [(set (match_operand:VD 0 "s_register_operand" "=w")
2694 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2695 (match_operand:VD 2 "s_register_operand" "w")
2696 (match_operand:SI 3 "immediate_operand" "i")]
2699 "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2700 ;; Assume this schedules like vmin.
2701 [(set (attr "neon_type")
2702 (if_then_else (match_test "<Is_float_mode>")
2703 (const_string "neon_fp_vadd_ddd_vabs_dd")
2704 (const_string "neon_int_5")))]
2707 (define_insn "neon_vrecps<mode>"
2708 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2709 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2710 (match_operand:VCVTF 2 "s_register_operand" "w")
2711 (match_operand:SI 3 "immediate_operand" "i")]
2714 "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2715 [(set (attr "neon_type")
2716 (if_then_else (match_test "<Is_d_reg>")
2717 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2718 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2721 (define_insn "neon_vrsqrts<mode>"
2722 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2723 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2724 (match_operand:VCVTF 2 "s_register_operand" "w")
2725 (match_operand:SI 3 "immediate_operand" "i")]
2728 "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2729 [(set (attr "neon_type")
2730 (if_then_else (match_test "<Is_d_reg>")
2731 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2732 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2735 (define_expand "neon_vabs<mode>"
2736 [(match_operand:VDQW 0 "s_register_operand" "")
2737 (match_operand:VDQW 1 "s_register_operand" "")
2738 (match_operand:SI 2 "immediate_operand" "")]
2741 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
2745 (define_insn "neon_vqabs<mode>"
2746 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2747 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2748 (match_operand:SI 2 "immediate_operand" "i")]
2751 "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2752 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2755 (define_expand "neon_vneg<mode>"
2756 [(match_operand:VDQW 0 "s_register_operand" "")
2757 (match_operand:VDQW 1 "s_register_operand" "")
2758 (match_operand:SI 2 "immediate_operand" "")]
2761 emit_insn (gen_neg<mode>2 (operands[0], operands[1]));
2765 (define_insn "neon_vqneg<mode>"
2766 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2767 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2768 (match_operand:SI 2 "immediate_operand" "i")]
2771 "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2772 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2775 (define_insn "neon_vcls<mode>"
2776 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2777 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2778 (match_operand:SI 2 "immediate_operand" "i")]
2781 "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2782 [(set_attr "neon_type" "neon_int_1")]
2785 (define_insn "clz<mode>2"
2786 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2787 (clz:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")))]
2789 "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1"
2790 [(set_attr "neon_type" "neon_int_1")]
2793 (define_expand "neon_vclz<mode>"
2794 [(match_operand:VDQIW 0 "s_register_operand" "")
2795 (match_operand:VDQIW 1 "s_register_operand" "")
2796 (match_operand:SI 2 "immediate_operand" "")]
2799 emit_insn (gen_clz<mode>2 (operands[0], operands[1]));
2803 (define_insn "popcount<mode>2"
2804 [(set (match_operand:VE 0 "s_register_operand" "=w")
2805 (popcount:VE (match_operand:VE 1 "s_register_operand" "w")))]
2807 "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2808 [(set_attr "neon_type" "neon_int_1")]
2811 (define_expand "neon_vcnt<mode>"
2812 [(match_operand:VE 0 "s_register_operand" "=w")
2813 (match_operand:VE 1 "s_register_operand" "w")
2814 (match_operand:SI 2 "immediate_operand" "i")]
2817 emit_insn (gen_popcount<mode>2 (operands[0], operands[1]));
2821 (define_insn "neon_vrecpe<mode>"
2822 [(set (match_operand:V32 0 "s_register_operand" "=w")
2823 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2824 (match_operand:SI 2 "immediate_operand" "i")]
2827 "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2828 [(set (attr "neon_type")
2829 (if_then_else (match_test "<Is_d_reg>")
2830 (const_string "neon_fp_vadd_ddd_vabs_dd")
2831 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2834 (define_insn "neon_vrsqrte<mode>"
2835 [(set (match_operand:V32 0 "s_register_operand" "=w")
2836 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2837 (match_operand:SI 2 "immediate_operand" "i")]
2840 "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2841 [(set (attr "neon_type")
2842 (if_then_else (match_test "<Is_d_reg>")
2843 (const_string "neon_fp_vadd_ddd_vabs_dd")
2844 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2847 (define_expand "neon_vmvn<mode>"
2848 [(match_operand:VDQIW 0 "s_register_operand" "")
2849 (match_operand:VDQIW 1 "s_register_operand" "")
2850 (match_operand:SI 2 "immediate_operand" "")]
2853 emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1]));
2857 (define_insn "neon_vget_lane<mode>_sext_internal"
2858 [(set (match_operand:SI 0 "s_register_operand" "=r")
2860 (vec_select:<V_elem>
2861 (match_operand:VD 1 "s_register_operand" "w")
2862 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2865 if (BYTES_BIG_ENDIAN)
2867 int elt = INTVAL (operands[2]);
2868 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2869 operands[2] = GEN_INT (elt);
2871 return "vmov.s<V_sz_elem>\t%0, %P1[%c2]";
2873 [(set_attr "neon_type" "neon_bp_simple")]
2876 (define_insn "neon_vget_lane<mode>_zext_internal"
2877 [(set (match_operand:SI 0 "s_register_operand" "=r")
2879 (vec_select:<V_elem>
2880 (match_operand:VD 1 "s_register_operand" "w")
2881 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2884 if (BYTES_BIG_ENDIAN)
2886 int elt = INTVAL (operands[2]);
2887 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2888 operands[2] = GEN_INT (elt);
2890 return "vmov.u<V_sz_elem>\t%0, %P1[%c2]";
2892 [(set_attr "neon_type" "neon_bp_simple")]
2895 (define_insn "neon_vget_lane<mode>_sext_internal"
2896 [(set (match_operand:SI 0 "s_register_operand" "=r")
2898 (vec_select:<V_elem>
2899 (match_operand:VQ 1 "s_register_operand" "w")
2900 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2904 int regno = REGNO (operands[1]);
2905 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2906 unsigned int elt = INTVAL (operands[2]);
2907 unsigned int elt_adj = elt % halfelts;
2909 if (BYTES_BIG_ENDIAN)
2910 elt_adj = halfelts - 1 - elt_adj;
2912 ops[0] = operands[0];
2913 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2914 ops[2] = GEN_INT (elt_adj);
2915 output_asm_insn ("vmov.s<V_sz_elem>\t%0, %P1[%c2]", ops);
2919 [(set_attr "neon_type" "neon_bp_simple")]
2922 (define_insn "neon_vget_lane<mode>_zext_internal"
2923 [(set (match_operand:SI 0 "s_register_operand" "=r")
2925 (vec_select:<V_elem>
2926 (match_operand:VQ 1 "s_register_operand" "w")
2927 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2931 int regno = REGNO (operands[1]);
2932 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2933 unsigned int elt = INTVAL (operands[2]);
2934 unsigned int elt_adj = elt % halfelts;
2936 if (BYTES_BIG_ENDIAN)
2937 elt_adj = halfelts - 1 - elt_adj;
2939 ops[0] = operands[0];
2940 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2941 ops[2] = GEN_INT (elt_adj);
2942 output_asm_insn ("vmov.u<V_sz_elem>\t%0, %P1[%c2]", ops);
2946 [(set_attr "neon_type" "neon_bp_simple")]
2949 (define_expand "neon_vget_lane<mode>"
2950 [(match_operand:<V_ext> 0 "s_register_operand" "")
2951 (match_operand:VDQW 1 "s_register_operand" "")
2952 (match_operand:SI 2 "immediate_operand" "")
2953 (match_operand:SI 3 "immediate_operand" "")]
2956 HOST_WIDE_INT magic = INTVAL (operands[3]);
2959 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode));
2961 if (BYTES_BIG_ENDIAN)
2963 /* The intrinsics are defined in terms of a model where the
2964 element ordering in memory is vldm order, whereas the generic
2965 RTL is defined in terms of a model where the element ordering
2966 in memory is array order. Convert the lane number to conform
2968 unsigned int elt = INTVAL (operands[2]);
2969 unsigned int reg_nelts
2970 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2971 elt ^= reg_nelts - 1;
2972 operands[2] = GEN_INT (elt);
2975 if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32)
2976 insn = gen_vec_extract<mode> (operands[0], operands[1], operands[2]);
2979 if ((magic & 1) != 0)
2980 insn = gen_neon_vget_lane<mode>_sext_internal (operands[0], operands[1],
2983 insn = gen_neon_vget_lane<mode>_zext_internal (operands[0], operands[1],
2990 ; Operand 3 (info word) is ignored because it does nothing useful with 64-bit
2993 (define_expand "neon_vget_lanedi"
2994 [(match_operand:DI 0 "s_register_operand" "=r")
2995 (match_operand:DI 1 "s_register_operand" "w")
2996 (match_operand:SI 2 "immediate_operand" "i")
2997 (match_operand:SI 3 "immediate_operand" "i")]
3000 neon_lane_bounds (operands[2], 0, 1);
3001 emit_move_insn (operands[0], operands[1]);
3005 (define_expand "neon_vget_lanev2di"
3006 [(match_operand:DI 0 "s_register_operand" "")
3007 (match_operand:V2DI 1 "s_register_operand" "")
3008 (match_operand:SI 2 "immediate_operand" "")
3009 (match_operand:SI 3 "immediate_operand" "")]
3012 switch (INTVAL (operands[2]))
3015 emit_move_insn (operands[0], gen_lowpart (DImode, operands[1]));
3018 emit_move_insn (operands[0], gen_highpart (DImode, operands[1]));
3021 neon_lane_bounds (operands[2], 0, 1);
3027 (define_expand "neon_vset_lane<mode>"
3028 [(match_operand:VDQ 0 "s_register_operand" "=w")
3029 (match_operand:<V_elem> 1 "s_register_operand" "r")
3030 (match_operand:VDQ 2 "s_register_operand" "0")
3031 (match_operand:SI 3 "immediate_operand" "i")]
3034 unsigned int elt = INTVAL (operands[3]);
3035 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3037 if (BYTES_BIG_ENDIAN)
3039 unsigned int reg_nelts
3040 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
3041 elt ^= reg_nelts - 1;
3044 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
3045 GEN_INT (1 << elt), operands[2]));
3049 ; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
3051 (define_expand "neon_vset_lanedi"
3052 [(match_operand:DI 0 "s_register_operand" "=w")
3053 (match_operand:DI 1 "s_register_operand" "r")
3054 (match_operand:DI 2 "s_register_operand" "0")
3055 (match_operand:SI 3 "immediate_operand" "i")]
3058 neon_lane_bounds (operands[3], 0, 1);
3059 emit_move_insn (operands[0], operands[1]);
3063 (define_expand "neon_vcreate<mode>"
3064 [(match_operand:VDX 0 "s_register_operand" "")
3065 (match_operand:DI 1 "general_operand" "")]
3068 rtx src = gen_lowpart (<MODE>mode, operands[1]);
3069 emit_move_insn (operands[0], src);
3073 (define_insn "neon_vdup_n<mode>"
3074 [(set (match_operand:VX 0 "s_register_operand" "=w")
3075 (vec_duplicate:VX (match_operand:<V_elem> 1 "s_register_operand" "r")))]
3077 "vdup.<V_sz_elem>\t%<V_reg>0, %1"
3078 ;; Assume this schedules like vmov.
3079 [(set_attr "neon_type" "neon_bp_simple")]
3082 (define_insn "neon_vdup_n<mode>"
3083 [(set (match_operand:V32 0 "s_register_operand" "=w,w")
3084 (vec_duplicate:V32 (match_operand:<V_elem> 1 "s_register_operand" "r,t")))]
3087 vdup.<V_sz_elem>\t%<V_reg>0, %1
3088 vdup.<V_sz_elem>\t%<V_reg>0, %y1"
3089 ;; Assume this schedules like vmov.
3090 [(set_attr "neon_type" "neon_bp_simple")]
3093 (define_expand "neon_vdup_ndi"
3094 [(match_operand:DI 0 "s_register_operand" "=w")
3095 (match_operand:DI 1 "s_register_operand" "r")]
3098 emit_move_insn (operands[0], operands[1]);
3103 (define_insn "neon_vdup_nv2di"
3104 [(set (match_operand:V2DI 0 "s_register_operand" "=w,w")
3105 (vec_duplicate:V2DI (match_operand:DI 1 "s_register_operand" "r,w")))]
3108 vmov\t%e0, %Q1, %R1\;vmov\t%f0, %Q1, %R1
3109 vmov\t%e0, %P1\;vmov\t%f0, %P1"
3110 [(set_attr "length" "8")
3111 (set_attr "neon_type" "neon_bp_simple")]
3114 (define_insn "neon_vdup_lane<mode>_internal"
3115 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3117 (vec_select:<V_elem>
3118 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
3119 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
3122 if (BYTES_BIG_ENDIAN)
3124 int elt = INTVAL (operands[2]);
3125 elt = GET_MODE_NUNITS (<V_double_vector_mode>mode) - 1 - elt;
3126 operands[2] = GEN_INT (elt);
3129 return "vdup.<V_sz_elem>\t%P0, %P1[%c2]";
3131 return "vdup.<V_sz_elem>\t%q0, %P1[%c2]";
3133 ;; Assume this schedules like vmov.
3134 [(set_attr "neon_type" "neon_bp_simple")]
3137 (define_expand "neon_vdup_lane<mode>"
3138 [(match_operand:VDQW 0 "s_register_operand" "=w")
3139 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
3140 (match_operand:SI 2 "immediate_operand" "i")]
3143 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<V_double_vector_mode>mode));
3144 if (BYTES_BIG_ENDIAN)
3146 unsigned int elt = INTVAL (operands[2]);
3147 unsigned int reg_nelts
3148 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<V_double_vector_mode>mode));
3149 elt ^= reg_nelts - 1;
3150 operands[2] = GEN_INT (elt);
3152 emit_insn (gen_neon_vdup_lane<mode>_internal (operands[0], operands[1],
3157 ; Scalar index is ignored, since only zero is valid here.
3158 (define_expand "neon_vdup_lanedi"
3159 [(match_operand:DI 0 "s_register_operand" "=w")
3160 (match_operand:DI 1 "s_register_operand" "w")
3161 (match_operand:SI 2 "immediate_operand" "i")]
3164 neon_lane_bounds (operands[2], 0, 1);
3165 emit_move_insn (operands[0], operands[1]);
3169 ; Likewise for v2di, as the DImode second operand has only a single element.
3170 (define_expand "neon_vdup_lanev2di"
3171 [(match_operand:V2DI 0 "s_register_operand" "=w")
3172 (match_operand:DI 1 "s_register_operand" "w")
3173 (match_operand:SI 2 "immediate_operand" "i")]
3176 neon_lane_bounds (operands[2], 0, 1);
3177 emit_insn (gen_neon_vdup_nv2di (operands[0], operands[1]));
3181 ; Disabled before reload because we don't want combine doing something silly,
3182 ; but used by the post-reload expansion of neon_vcombine.
3183 (define_insn "*neon_vswp<mode>"
3184 [(set (match_operand:VDQX 0 "s_register_operand" "+w")
3185 (match_operand:VDQX 1 "s_register_operand" "+w"))
3186 (set (match_dup 1) (match_dup 0))]
3187 "TARGET_NEON && reload_completed"
3188 "vswp\t%<V_reg>0, %<V_reg>1"
3189 [(set (attr "neon_type")
3190 (if_then_else (match_test "<Is_d_reg>")
3191 (const_string "neon_bp_simple")
3192 (const_string "neon_bp_2cycle")))]
3195 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
3197 ;; FIXME: A different implementation of this builtin could make it much
3198 ;; more likely that we wouldn't actually need to output anything (we could make
3199 ;; it so that the reg allocator puts things in the right places magically
3200 ;; instead). Lack of subregs for vectors makes that tricky though, I think.
3202 (define_insn_and_split "neon_vcombine<mode>"
3203 [(set (match_operand:<V_DOUBLE> 0 "s_register_operand" "=w")
3204 (vec_concat:<V_DOUBLE>
3205 (match_operand:VDX 1 "s_register_operand" "w")
3206 (match_operand:VDX 2 "s_register_operand" "w")))]
3209 "&& reload_completed"
3212 neon_split_vcombine (operands);
3216 (define_expand "neon_vget_high<mode>"
3217 [(match_operand:<V_HALF> 0 "s_register_operand")
3218 (match_operand:VQX 1 "s_register_operand")]
3221 emit_move_insn (operands[0],
3222 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode,
3223 GET_MODE_SIZE (<V_HALF>mode)));
3227 (define_expand "neon_vget_low<mode>"
3228 [(match_operand:<V_HALF> 0 "s_register_operand")
3229 (match_operand:VQX 1 "s_register_operand")]
3232 emit_move_insn (operands[0],
3233 simplify_gen_subreg (<V_HALF>mode, operands[1],
3238 (define_insn "float<mode><V_cvtto>2"
3239 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3240 (float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))]
3241 "TARGET_NEON && !flag_rounding_math"
3242 "vcvt.f32.s32\t%<V_reg>0, %<V_reg>1"
3243 [(set (attr "neon_type")
3244 (if_then_else (match_test "<Is_d_reg>")
3245 (const_string "neon_fp_vadd_ddd_vabs_dd")
3246 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3249 (define_insn "floatuns<mode><V_cvtto>2"
3250 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3251 (unsigned_float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))]
3252 "TARGET_NEON && !flag_rounding_math"
3253 "vcvt.f32.u32\t%<V_reg>0, %<V_reg>1"
3254 [(set (attr "neon_type")
3255 (if_then_else (match_test "<Is_d_reg>")
3256 (const_string "neon_fp_vadd_ddd_vabs_dd")
3257 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3260 (define_insn "fix_trunc<mode><V_cvtto>2"
3261 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3262 (fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))]
3264 "vcvt.s32.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 "fixuns_trunc<mode><V_cvtto>2"
3272 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3273 (unsigned_fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))]
3275 "vcvt.u32.f32\t%<V_reg>0, %<V_reg>1"
3276 [(set (attr "neon_type")
3277 (if_then_else (match_test "<Is_d_reg>")
3278 (const_string "neon_fp_vadd_ddd_vabs_dd")
3279 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3282 (define_insn "neon_vcvt<mode>"
3283 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3284 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3285 (match_operand:SI 2 "immediate_operand" "i")]
3288 "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1"
3289 [(set (attr "neon_type")
3290 (if_then_else (match_test "<Is_d_reg>")
3291 (const_string "neon_fp_vadd_ddd_vabs_dd")
3292 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3295 (define_insn "neon_vcvt<mode>"
3296 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3297 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3298 (match_operand:SI 2 "immediate_operand" "i")]
3301 "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1"
3302 [(set (attr "neon_type")
3303 (if_then_else (match_test "<Is_d_reg>")
3304 (const_string "neon_fp_vadd_ddd_vabs_dd")
3305 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3308 (define_insn "neon_vcvt_n<mode>"
3309 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3310 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3311 (match_operand:SI 2 "immediate_operand" "i")
3312 (match_operand:SI 3 "immediate_operand" "i")]
3316 neon_const_bounds (operands[2], 1, 33);
3317 return "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2";
3319 [(set (attr "neon_type")
3320 (if_then_else (match_test "<Is_d_reg>")
3321 (const_string "neon_fp_vadd_ddd_vabs_dd")
3322 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3325 (define_insn "neon_vcvt_n<mode>"
3326 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3327 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3328 (match_operand:SI 2 "immediate_operand" "i")
3329 (match_operand:SI 3 "immediate_operand" "i")]
3333 neon_const_bounds (operands[2], 1, 33);
3334 return "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2";
3336 [(set (attr "neon_type")
3337 (if_then_else (match_test "<Is_d_reg>")
3338 (const_string "neon_fp_vadd_ddd_vabs_dd")
3339 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3342 (define_insn "neon_vmovn<mode>"
3343 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3344 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3345 (match_operand:SI 2 "immediate_operand" "i")]
3348 "vmovn.<V_if_elem>\t%P0, %q1"
3349 [(set_attr "neon_type" "neon_bp_simple")]
3352 (define_insn "neon_vqmovn<mode>"
3353 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3354 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3355 (match_operand:SI 2 "immediate_operand" "i")]
3358 "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1"
3359 [(set_attr "neon_type" "neon_shift_2")]
3362 (define_insn "neon_vqmovun<mode>"
3363 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3364 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3365 (match_operand:SI 2 "immediate_operand" "i")]
3368 "vqmovun.<V_s_elem>\t%P0, %q1"
3369 [(set_attr "neon_type" "neon_shift_2")]
3372 (define_insn "neon_vmovl<mode>"
3373 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3374 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
3375 (match_operand:SI 2 "immediate_operand" "i")]
3378 "vmovl.%T2%#<V_sz_elem>\t%q0, %P1"
3379 [(set_attr "neon_type" "neon_shift_1")]
3382 (define_insn "neon_vmul_lane<mode>"
3383 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3384 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
3385 (match_operand:VMD 2 "s_register_operand"
3386 "<scalar_mul_constraint>")
3387 (match_operand:SI 3 "immediate_operand" "i")
3388 (match_operand:SI 4 "immediate_operand" "i")]
3392 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3393 return "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]";
3395 [(set (attr "neon_type")
3396 (if_then_else (match_test "<Is_float_mode>")
3397 (const_string "neon_fp_vmul_ddd")
3398 (if_then_else (match_test "<Scalar_mul_8_16>")
3399 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3400 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))))]
3403 (define_insn "neon_vmul_lane<mode>"
3404 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3405 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
3406 (match_operand:<V_HALF> 2 "s_register_operand"
3407 "<scalar_mul_constraint>")
3408 (match_operand:SI 3 "immediate_operand" "i")
3409 (match_operand:SI 4 "immediate_operand" "i")]
3413 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<V_HALF>mode));
3414 return "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]";
3416 [(set (attr "neon_type")
3417 (if_then_else (match_test "<Is_float_mode>")
3418 (const_string "neon_fp_vmul_qqd")
3419 (if_then_else (match_test "<Scalar_mul_8_16>")
3420 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3421 (const_string "neon_mul_qqd_32_scalar"))))]
3424 (define_insn "neon_vmull_lane<mode>"
3425 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3426 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3427 (match_operand:VMDI 2 "s_register_operand"
3428 "<scalar_mul_constraint>")
3429 (match_operand:SI 3 "immediate_operand" "i")
3430 (match_operand:SI 4 "immediate_operand" "i")]
3431 UNSPEC_VMULL_LANE))]
3434 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3435 return "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]";
3437 [(set (attr "neon_type")
3438 (if_then_else (match_test "<Scalar_mul_8_16>")
3439 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3440 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3443 (define_insn "neon_vqdmull_lane<mode>"
3444 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3445 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3446 (match_operand:VMDI 2 "s_register_operand"
3447 "<scalar_mul_constraint>")
3448 (match_operand:SI 3 "immediate_operand" "i")
3449 (match_operand:SI 4 "immediate_operand" "i")]
3450 UNSPEC_VQDMULL_LANE))]
3453 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3454 return "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]";
3456 [(set (attr "neon_type")
3457 (if_then_else (match_test "<Scalar_mul_8_16>")
3458 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3459 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3462 (define_insn "neon_vqdmulh_lane<mode>"
3463 [(set (match_operand:VMQI 0 "s_register_operand" "=w")
3464 (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
3465 (match_operand:<V_HALF> 2 "s_register_operand"
3466 "<scalar_mul_constraint>")
3467 (match_operand:SI 3 "immediate_operand" "i")
3468 (match_operand:SI 4 "immediate_operand" "i")]
3469 UNSPEC_VQDMULH_LANE))]
3472 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3473 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]";
3475 [(set (attr "neon_type")
3476 (if_then_else (match_test "<Scalar_mul_8_16>")
3477 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3478 (const_string "neon_mul_qqd_32_scalar")))]
3481 (define_insn "neon_vqdmulh_lane<mode>"
3482 [(set (match_operand:VMDI 0 "s_register_operand" "=w")
3483 (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
3484 (match_operand:VMDI 2 "s_register_operand"
3485 "<scalar_mul_constraint>")
3486 (match_operand:SI 3 "immediate_operand" "i")
3487 (match_operand:SI 4 "immediate_operand" "i")]
3488 UNSPEC_VQDMULH_LANE))]
3491 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3492 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]";
3494 [(set (attr "neon_type")
3495 (if_then_else (match_test "<Scalar_mul_8_16>")
3496 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3497 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3500 (define_insn "neon_vmla_lane<mode>"
3501 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3502 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3503 (match_operand:VMD 2 "s_register_operand" "w")
3504 (match_operand:VMD 3 "s_register_operand"
3505 "<scalar_mul_constraint>")
3506 (match_operand:SI 4 "immediate_operand" "i")
3507 (match_operand:SI 5 "immediate_operand" "i")]
3511 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3512 return "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3514 [(set (attr "neon_type")
3515 (if_then_else (match_test "<Is_float_mode>")
3516 (const_string "neon_fp_vmla_ddd_scalar")
3517 (if_then_else (match_test "<Scalar_mul_8_16>")
3518 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3519 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3522 (define_insn "neon_vmla_lane<mode>"
3523 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3524 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3525 (match_operand:VMQ 2 "s_register_operand" "w")
3526 (match_operand:<V_HALF> 3 "s_register_operand"
3527 "<scalar_mul_constraint>")
3528 (match_operand:SI 4 "immediate_operand" "i")
3529 (match_operand:SI 5 "immediate_operand" "i")]
3533 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3534 return "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3536 [(set (attr "neon_type")
3537 (if_then_else (match_test "<Is_float_mode>")
3538 (const_string "neon_fp_vmla_qqq_scalar")
3539 (if_then_else (match_test "<Scalar_mul_8_16>")
3540 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3541 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3544 (define_insn "neon_vmlal_lane<mode>"
3545 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3546 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3547 (match_operand:VMDI 2 "s_register_operand" "w")
3548 (match_operand:VMDI 3 "s_register_operand"
3549 "<scalar_mul_constraint>")
3550 (match_operand:SI 4 "immediate_operand" "i")
3551 (match_operand:SI 5 "immediate_operand" "i")]
3552 UNSPEC_VMLAL_LANE))]
3555 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3556 return "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3558 [(set (attr "neon_type")
3559 (if_then_else (match_test "<Scalar_mul_8_16>")
3560 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3561 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3564 (define_insn "neon_vqdmlal_lane<mode>"
3565 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3566 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3567 (match_operand:VMDI 2 "s_register_operand" "w")
3568 (match_operand:VMDI 3 "s_register_operand"
3569 "<scalar_mul_constraint>")
3570 (match_operand:SI 4 "immediate_operand" "i")
3571 (match_operand:SI 5 "immediate_operand" "i")]
3572 UNSPEC_VQDMLAL_LANE))]
3575 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3576 return "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3578 [(set (attr "neon_type")
3579 (if_then_else (match_test "<Scalar_mul_8_16>")
3580 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3581 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3584 (define_insn "neon_vmls_lane<mode>"
3585 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3586 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3587 (match_operand:VMD 2 "s_register_operand" "w")
3588 (match_operand:VMD 3 "s_register_operand"
3589 "<scalar_mul_constraint>")
3590 (match_operand:SI 4 "immediate_operand" "i")
3591 (match_operand:SI 5 "immediate_operand" "i")]
3595 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3596 return "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3598 [(set (attr "neon_type")
3599 (if_then_else (match_test "<Is_float_mode>")
3600 (const_string "neon_fp_vmla_ddd_scalar")
3601 (if_then_else (match_test "<Scalar_mul_8_16>")
3602 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3603 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3606 (define_insn "neon_vmls_lane<mode>"
3607 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3608 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3609 (match_operand:VMQ 2 "s_register_operand" "w")
3610 (match_operand:<V_HALF> 3 "s_register_operand"
3611 "<scalar_mul_constraint>")
3612 (match_operand:SI 4 "immediate_operand" "i")
3613 (match_operand:SI 5 "immediate_operand" "i")]
3617 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3618 return "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3620 [(set (attr "neon_type")
3621 (if_then_else (match_test "<Is_float_mode>")
3622 (const_string "neon_fp_vmla_qqq_scalar")
3623 (if_then_else (match_test "<Scalar_mul_8_16>")
3624 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3625 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3628 (define_insn "neon_vmlsl_lane<mode>"
3629 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3630 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3631 (match_operand:VMDI 2 "s_register_operand" "w")
3632 (match_operand:VMDI 3 "s_register_operand"
3633 "<scalar_mul_constraint>")
3634 (match_operand:SI 4 "immediate_operand" "i")
3635 (match_operand:SI 5 "immediate_operand" "i")]
3636 UNSPEC_VMLSL_LANE))]
3639 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3640 return "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3642 [(set (attr "neon_type")
3643 (if_then_else (match_test "<Scalar_mul_8_16>")
3644 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3645 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3648 (define_insn "neon_vqdmlsl_lane<mode>"
3649 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3650 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3651 (match_operand:VMDI 2 "s_register_operand" "w")
3652 (match_operand:VMDI 3 "s_register_operand"
3653 "<scalar_mul_constraint>")
3654 (match_operand:SI 4 "immediate_operand" "i")
3655 (match_operand:SI 5 "immediate_operand" "i")]
3656 UNSPEC_VQDMLSL_LANE))]
3659 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3660 return "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3662 [(set (attr "neon_type")
3663 (if_then_else (match_test "<Scalar_mul_8_16>")
3664 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3665 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3668 ; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
3669 ; core register into a temp register, then use a scalar taken from that. This
3670 ; isn't an optimal solution if e.g. the scalar has just been read from memory
3671 ; or extracted from another vector. The latter case it's currently better to
3672 ; use the "_lane" variant, and the former case can probably be implemented
3673 ; using vld1_lane, but that hasn't been done yet.
3675 (define_expand "neon_vmul_n<mode>"
3676 [(match_operand:VMD 0 "s_register_operand" "")
3677 (match_operand:VMD 1 "s_register_operand" "")
3678 (match_operand:<V_elem> 2 "s_register_operand" "")
3679 (match_operand:SI 3 "immediate_operand" "")]
3682 rtx tmp = gen_reg_rtx (<MODE>mode);
3683 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3684 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3685 const0_rtx, const0_rtx));
3689 (define_expand "neon_vmul_n<mode>"
3690 [(match_operand:VMQ 0 "s_register_operand" "")
3691 (match_operand:VMQ 1 "s_register_operand" "")
3692 (match_operand:<V_elem> 2 "s_register_operand" "")
3693 (match_operand:SI 3 "immediate_operand" "")]
3696 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3697 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3698 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3699 const0_rtx, const0_rtx));
3703 (define_expand "neon_vmull_n<mode>"
3704 [(match_operand:<V_widen> 0 "s_register_operand" "")
3705 (match_operand:VMDI 1 "s_register_operand" "")
3706 (match_operand:<V_elem> 2 "s_register_operand" "")
3707 (match_operand:SI 3 "immediate_operand" "")]
3710 rtx tmp = gen_reg_rtx (<MODE>mode);
3711 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3712 emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp,
3713 const0_rtx, operands[3]));
3717 (define_expand "neon_vqdmull_n<mode>"
3718 [(match_operand:<V_widen> 0 "s_register_operand" "")
3719 (match_operand:VMDI 1 "s_register_operand" "")
3720 (match_operand:<V_elem> 2 "s_register_operand" "")
3721 (match_operand:SI 3 "immediate_operand" "")]
3724 rtx tmp = gen_reg_rtx (<MODE>mode);
3725 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3726 emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp,
3727 const0_rtx, const0_rtx));
3731 (define_expand "neon_vqdmulh_n<mode>"
3732 [(match_operand:VMDI 0 "s_register_operand" "")
3733 (match_operand:VMDI 1 "s_register_operand" "")
3734 (match_operand:<V_elem> 2 "s_register_operand" "")
3735 (match_operand:SI 3 "immediate_operand" "")]
3738 rtx tmp = gen_reg_rtx (<MODE>mode);
3739 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3740 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3741 const0_rtx, operands[3]));
3745 (define_expand "neon_vqdmulh_n<mode>"
3746 [(match_operand:VMQI 0 "s_register_operand" "")
3747 (match_operand:VMQI 1 "s_register_operand" "")
3748 (match_operand:<V_elem> 2 "s_register_operand" "")
3749 (match_operand:SI 3 "immediate_operand" "")]
3752 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3753 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3754 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3755 const0_rtx, operands[3]));
3759 (define_expand "neon_vmla_n<mode>"
3760 [(match_operand:VMD 0 "s_register_operand" "")
3761 (match_operand:VMD 1 "s_register_operand" "")
3762 (match_operand:VMD 2 "s_register_operand" "")
3763 (match_operand:<V_elem> 3 "s_register_operand" "")
3764 (match_operand:SI 4 "immediate_operand" "")]
3767 rtx tmp = gen_reg_rtx (<MODE>mode);
3768 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3769 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3770 tmp, const0_rtx, operands[4]));
3774 (define_expand "neon_vmla_n<mode>"
3775 [(match_operand:VMQ 0 "s_register_operand" "")
3776 (match_operand:VMQ 1 "s_register_operand" "")
3777 (match_operand:VMQ 2 "s_register_operand" "")
3778 (match_operand:<V_elem> 3 "s_register_operand" "")
3779 (match_operand:SI 4 "immediate_operand" "")]
3782 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3783 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3784 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3785 tmp, const0_rtx, operands[4]));
3789 (define_expand "neon_vmlal_n<mode>"
3790 [(match_operand:<V_widen> 0 "s_register_operand" "")
3791 (match_operand:<V_widen> 1 "s_register_operand" "")
3792 (match_operand:VMDI 2 "s_register_operand" "")
3793 (match_operand:<V_elem> 3 "s_register_operand" "")
3794 (match_operand:SI 4 "immediate_operand" "")]
3797 rtx tmp = gen_reg_rtx (<MODE>mode);
3798 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3799 emit_insn (gen_neon_vmlal_lane<mode> (operands[0], operands[1], operands[2],
3800 tmp, const0_rtx, operands[4]));
3804 (define_expand "neon_vqdmlal_n<mode>"
3805 [(match_operand:<V_widen> 0 "s_register_operand" "")
3806 (match_operand:<V_widen> 1 "s_register_operand" "")
3807 (match_operand:VMDI 2 "s_register_operand" "")
3808 (match_operand:<V_elem> 3 "s_register_operand" "")
3809 (match_operand:SI 4 "immediate_operand" "")]
3812 rtx tmp = gen_reg_rtx (<MODE>mode);
3813 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3814 emit_insn (gen_neon_vqdmlal_lane<mode> (operands[0], operands[1], operands[2],
3815 tmp, const0_rtx, operands[4]));
3819 (define_expand "neon_vmls_n<mode>"
3820 [(match_operand:VMD 0 "s_register_operand" "")
3821 (match_operand:VMD 1 "s_register_operand" "")
3822 (match_operand:VMD 2 "s_register_operand" "")
3823 (match_operand:<V_elem> 3 "s_register_operand" "")
3824 (match_operand:SI 4 "immediate_operand" "")]
3827 rtx tmp = gen_reg_rtx (<MODE>mode);
3828 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3829 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3830 tmp, const0_rtx, operands[4]));
3834 (define_expand "neon_vmls_n<mode>"
3835 [(match_operand:VMQ 0 "s_register_operand" "")
3836 (match_operand:VMQ 1 "s_register_operand" "")
3837 (match_operand:VMQ 2 "s_register_operand" "")
3838 (match_operand:<V_elem> 3 "s_register_operand" "")
3839 (match_operand:SI 4 "immediate_operand" "")]
3842 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3843 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3844 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3845 tmp, const0_rtx, operands[4]));
3849 (define_expand "neon_vmlsl_n<mode>"
3850 [(match_operand:<V_widen> 0 "s_register_operand" "")
3851 (match_operand:<V_widen> 1 "s_register_operand" "")
3852 (match_operand:VMDI 2 "s_register_operand" "")
3853 (match_operand:<V_elem> 3 "s_register_operand" "")
3854 (match_operand:SI 4 "immediate_operand" "")]
3857 rtx tmp = gen_reg_rtx (<MODE>mode);
3858 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3859 emit_insn (gen_neon_vmlsl_lane<mode> (operands[0], operands[1], operands[2],
3860 tmp, const0_rtx, operands[4]));
3864 (define_expand "neon_vqdmlsl_n<mode>"
3865 [(match_operand:<V_widen> 0 "s_register_operand" "")
3866 (match_operand:<V_widen> 1 "s_register_operand" "")
3867 (match_operand:VMDI 2 "s_register_operand" "")
3868 (match_operand:<V_elem> 3 "s_register_operand" "")
3869 (match_operand:SI 4 "immediate_operand" "")]
3872 rtx tmp = gen_reg_rtx (<MODE>mode);
3873 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3874 emit_insn (gen_neon_vqdmlsl_lane<mode> (operands[0], operands[1], operands[2],
3875 tmp, const0_rtx, operands[4]));
3879 (define_insn "neon_vext<mode>"
3880 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
3881 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
3882 (match_operand:VDQX 2 "s_register_operand" "w")
3883 (match_operand:SI 3 "immediate_operand" "i")]
3887 neon_const_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3888 return "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3";
3890 [(set (attr "neon_type")
3891 (if_then_else (match_test "<Is_d_reg>")
3892 (const_string "neon_bp_simple")
3893 (const_string "neon_bp_2cycle")))]
3896 (define_insn "neon_vrev64<mode>"
3897 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
3898 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
3899 (match_operand:SI 2 "immediate_operand" "i")]
3902 "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3903 [(set_attr "neon_type" "neon_bp_simple")]
3906 (define_insn "neon_vrev32<mode>"
3907 [(set (match_operand:VX 0 "s_register_operand" "=w")
3908 (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")
3909 (match_operand:SI 2 "immediate_operand" "i")]
3912 "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3913 [(set_attr "neon_type" "neon_bp_simple")]
3916 (define_insn "neon_vrev16<mode>"
3917 [(set (match_operand:VE 0 "s_register_operand" "=w")
3918 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
3919 (match_operand:SI 2 "immediate_operand" "i")]
3922 "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3923 [(set_attr "neon_type" "neon_bp_simple")]
3926 ; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
3927 ; allocation. For an intrinsic of form:
3928 ; rD = vbsl_* (rS, rN, rM)
3929 ; We can use any of:
3930 ; vbsl rS, rN, rM (if D = S)
3931 ; vbit rD, rN, rS (if D = M, so 1-bits in rS choose bits from rN, else rM)
3932 ; vbif rD, rM, rS (if D = N, so 0-bits in rS choose bits from rM, else rN)
3934 (define_insn "neon_vbsl<mode>_internal"
3935 [(set (match_operand:VDQX 0 "s_register_operand" "=w,w,w")
3936 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" " 0,w,w")
3937 (match_operand:VDQX 2 "s_register_operand" " w,w,0")
3938 (match_operand:VDQX 3 "s_register_operand" " w,0,w")]
3942 vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3
3943 vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1
3944 vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1"
3945 [(set_attr "neon_type" "neon_int_1")]
3948 (define_expand "neon_vbsl<mode>"
3949 [(set (match_operand:VDQX 0 "s_register_operand" "")
3950 (unspec:VDQX [(match_operand:<V_cmp_result> 1 "s_register_operand" "")
3951 (match_operand:VDQX 2 "s_register_operand" "")
3952 (match_operand:VDQX 3 "s_register_operand" "")]
3956 /* We can't alias operands together if they have different modes. */
3957 operands[1] = gen_lowpart (<MODE>mode, operands[1]);
3960 (define_insn "neon_vshl<mode>"
3961 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3962 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3963 (match_operand:VDQIX 2 "s_register_operand" "w")
3964 (match_operand:SI 3 "immediate_operand" "i")]
3967 "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3968 [(set (attr "neon_type")
3969 (if_then_else (match_test "<Is_d_reg>")
3970 (const_string "neon_vshl_ddd")
3971 (const_string "neon_shift_3")))]
3974 (define_insn "neon_vqshl<mode>"
3975 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3976 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3977 (match_operand:VDQIX 2 "s_register_operand" "w")
3978 (match_operand:SI 3 "immediate_operand" "i")]
3981 "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3982 [(set (attr "neon_type")
3983 (if_then_else (match_test "<Is_d_reg>")
3984 (const_string "neon_shift_2")
3985 (const_string "neon_vqshl_vrshl_vqrshl_qqq")))]
3988 (define_insn "neon_vshr_n<mode>"
3989 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3990 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3991 (match_operand:SI 2 "immediate_operand" "i")
3992 (match_operand:SI 3 "immediate_operand" "i")]
3996 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) + 1);
3997 return "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3999 [(set_attr "neon_type" "neon_shift_1")]
4002 (define_insn "neon_vshrn_n<mode>"
4003 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
4004 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
4005 (match_operand:SI 2 "immediate_operand" "i")
4006 (match_operand:SI 3 "immediate_operand" "i")]
4010 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
4011 return "v%O3shrn.<V_if_elem>\t%P0, %q1, %2";
4013 [(set_attr "neon_type" "neon_shift_1")]
4016 (define_insn "neon_vqshrn_n<mode>"
4017 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
4018 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
4019 (match_operand:SI 2 "immediate_operand" "i")
4020 (match_operand:SI 3 "immediate_operand" "i")]
4024 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
4025 return "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2";
4027 [(set_attr "neon_type" "neon_shift_2")]
4030 (define_insn "neon_vqshrun_n<mode>"
4031 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
4032 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
4033 (match_operand:SI 2 "immediate_operand" "i")
4034 (match_operand:SI 3 "immediate_operand" "i")]
4038 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
4039 return "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2";
4041 [(set_attr "neon_type" "neon_shift_2")]
4044 (define_insn "neon_vshl_n<mode>"
4045 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4046 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
4047 (match_operand:SI 2 "immediate_operand" "i")
4048 (match_operand:SI 3 "immediate_operand" "i")]
4052 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
4053 return "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2";
4055 [(set_attr "neon_type" "neon_shift_1")]
4058 (define_insn "neon_vqshl_n<mode>"
4059 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4060 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
4061 (match_operand:SI 2 "immediate_operand" "i")
4062 (match_operand:SI 3 "immediate_operand" "i")]
4066 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
4067 return "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
4069 [(set_attr "neon_type" "neon_shift_2")]
4072 (define_insn "neon_vqshlu_n<mode>"
4073 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4074 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
4075 (match_operand:SI 2 "immediate_operand" "i")
4076 (match_operand:SI 3 "immediate_operand" "i")]
4080 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
4081 return "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
4083 [(set_attr "neon_type" "neon_shift_2")]
4086 (define_insn "neon_vshll_n<mode>"
4087 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
4088 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
4089 (match_operand:SI 2 "immediate_operand" "i")
4090 (match_operand:SI 3 "immediate_operand" "i")]
4094 /* The boundaries are: 0 < imm <= size. */
4095 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode) + 1);
4096 return "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2";
4098 [(set_attr "neon_type" "neon_shift_1")]
4101 (define_insn "neon_vsra_n<mode>"
4102 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4103 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4104 (match_operand:VDQIX 2 "s_register_operand" "w")
4105 (match_operand:SI 3 "immediate_operand" "i")
4106 (match_operand:SI 4 "immediate_operand" "i")]
4110 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
4111 return "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4113 [(set_attr "neon_type" "neon_vsra_vrsra")]
4116 (define_insn "neon_vsri_n<mode>"
4117 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4118 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4119 (match_operand:VDQIX 2 "s_register_operand" "w")
4120 (match_operand:SI 3 "immediate_operand" "i")]
4124 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
4125 return "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4127 [(set (attr "neon_type")
4128 (if_then_else (match_test "<Is_d_reg>")
4129 (const_string "neon_shift_1")
4130 (const_string "neon_shift_3")))]
4133 (define_insn "neon_vsli_n<mode>"
4134 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4135 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4136 (match_operand:VDQIX 2 "s_register_operand" "w")
4137 (match_operand:SI 3 "immediate_operand" "i")]
4141 neon_const_bounds (operands[3], 0, neon_element_bits (<MODE>mode));
4142 return "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4144 [(set (attr "neon_type")
4145 (if_then_else (match_test "<Is_d_reg>")
4146 (const_string "neon_shift_1")
4147 (const_string "neon_shift_3")))]
4150 (define_insn "neon_vtbl1v8qi"
4151 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4152 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")
4153 (match_operand:V8QI 2 "s_register_operand" "w")]
4156 "vtbl.8\t%P0, {%P1}, %P2"
4157 [(set_attr "neon_type" "neon_bp_2cycle")]
4160 (define_insn "neon_vtbl2v8qi"
4161 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4162 (unspec:V8QI [(match_operand:TI 1 "s_register_operand" "w")
4163 (match_operand:V8QI 2 "s_register_operand" "w")]
4168 int tabbase = REGNO (operands[1]);
4170 ops[0] = operands[0];
4171 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4172 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4173 ops[3] = operands[2];
4174 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2}, %P3", ops);
4178 [(set_attr "neon_type" "neon_bp_2cycle")]
4181 (define_insn "neon_vtbl3v8qi"
4182 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4183 (unspec:V8QI [(match_operand:EI 1 "s_register_operand" "w")
4184 (match_operand:V8QI 2 "s_register_operand" "w")]
4189 int tabbase = REGNO (operands[1]);
4191 ops[0] = operands[0];
4192 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4193 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4194 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4195 ops[4] = operands[2];
4196 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
4200 [(set_attr "neon_type" "neon_bp_3cycle")]
4203 (define_insn "neon_vtbl4v8qi"
4204 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4205 (unspec:V8QI [(match_operand:OI 1 "s_register_operand" "w")
4206 (match_operand:V8QI 2 "s_register_operand" "w")]
4211 int tabbase = REGNO (operands[1]);
4213 ops[0] = operands[0];
4214 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4215 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4216 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4217 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4218 ops[5] = operands[2];
4219 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4223 [(set_attr "neon_type" "neon_bp_3cycle")]
4226 ;; These three are used by the vec_perm infrastructure for V16QImode.
4227 (define_insn_and_split "neon_vtbl1v16qi"
4228 [(set (match_operand:V16QI 0 "s_register_operand" "=&w")
4229 (unspec:V16QI [(match_operand:V16QI 1 "s_register_operand" "w")
4230 (match_operand:V16QI 2 "s_register_operand" "w")]
4234 "&& reload_completed"
4237 rtx op0, op1, op2, part0, part2;
4241 op1 = gen_lowpart (TImode, operands[1]);
4244 ofs = subreg_lowpart_offset (V8QImode, V16QImode);
4245 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4246 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4247 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4249 ofs = subreg_highpart_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));
4256 (define_insn_and_split "neon_vtbl2v16qi"
4257 [(set (match_operand:V16QI 0 "s_register_operand" "=&w")
4258 (unspec:V16QI [(match_operand:OI 1 "s_register_operand" "w")
4259 (match_operand:V16QI 2 "s_register_operand" "w")]
4263 "&& reload_completed"
4266 rtx op0, op1, op2, part0, part2;
4273 ofs = subreg_lowpart_offset (V8QImode, V16QImode);
4274 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4275 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4276 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4278 ofs = subreg_highpart_offset (V8QImode, V16QImode);
4279 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4280 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4281 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4285 ;; ??? Logically we should extend the regular neon_vcombine pattern to
4286 ;; handle quad-word input modes, producing octa-word output modes. But
4287 ;; that requires us to add support for octa-word vector modes in moves.
4288 ;; That seems overkill for this one use in vec_perm.
4289 (define_insn_and_split "neon_vcombinev16qi"
4290 [(set (match_operand:OI 0 "s_register_operand" "=w")
4291 (unspec:OI [(match_operand:V16QI 1 "s_register_operand" "w")
4292 (match_operand:V16QI 2 "s_register_operand" "w")]
4296 "&& reload_completed"
4299 neon_split_vcombine (operands);
4303 (define_insn "neon_vtbx1v8qi"
4304 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4305 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4306 (match_operand:V8QI 2 "s_register_operand" "w")
4307 (match_operand:V8QI 3 "s_register_operand" "w")]
4310 "vtbx.8\t%P0, {%P2}, %P3"
4311 [(set_attr "neon_type" "neon_bp_2cycle")]
4314 (define_insn "neon_vtbx2v8qi"
4315 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4316 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4317 (match_operand:TI 2 "s_register_operand" "w")
4318 (match_operand:V8QI 3 "s_register_operand" "w")]
4323 int tabbase = REGNO (operands[2]);
4325 ops[0] = operands[0];
4326 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4327 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4328 ops[3] = operands[3];
4329 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2}, %P3", ops);
4333 [(set_attr "neon_type" "neon_bp_2cycle")]
4336 (define_insn "neon_vtbx3v8qi"
4337 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4338 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4339 (match_operand:EI 2 "s_register_operand" "w")
4340 (match_operand:V8QI 3 "s_register_operand" "w")]
4345 int tabbase = REGNO (operands[2]);
4347 ops[0] = operands[0];
4348 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4349 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4350 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4351 ops[4] = operands[3];
4352 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
4356 [(set_attr "neon_type" "neon_bp_3cycle")]
4359 (define_insn "neon_vtbx4v8qi"
4360 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4361 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4362 (match_operand:OI 2 "s_register_operand" "w")
4363 (match_operand:V8QI 3 "s_register_operand" "w")]
4368 int tabbase = REGNO (operands[2]);
4370 ops[0] = operands[0];
4371 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4372 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4373 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4374 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4375 ops[5] = operands[3];
4376 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4380 [(set_attr "neon_type" "neon_bp_3cycle")]
4383 (define_expand "neon_vtrn<mode>_internal"
4385 [(set (match_operand:VDQW 0 "s_register_operand" "")
4386 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4387 (match_operand:VDQW 2 "s_register_operand" "")]
4389 (set (match_operand:VDQW 3 "s_register_operand" "")
4390 (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VTRN2))])]
4395 ;; Note: Different operand numbering to handle tied registers correctly.
4396 (define_insn "*neon_vtrn<mode>_insn"
4397 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4398 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4399 (match_operand:VDQW 3 "s_register_operand" "2")]
4401 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4402 (unspec:VDQW [(match_dup 1) (match_dup 3)]
4405 "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4406 [(set (attr "neon_type")
4407 (if_then_else (match_test "<Is_d_reg>")
4408 (const_string "neon_bp_simple")
4409 (const_string "neon_bp_3cycle")))]
4412 (define_expand "neon_vtrn<mode>"
4413 [(match_operand:SI 0 "s_register_operand" "r")
4414 (match_operand:VDQW 1 "s_register_operand" "w")
4415 (match_operand:VDQW 2 "s_register_operand" "w")]
4418 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vtrn<mode>_internal,
4419 operands[0], operands[1], operands[2]);
4423 (define_expand "neon_vzip<mode>_internal"
4425 [(set (match_operand:VDQW 0 "s_register_operand" "")
4426 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4427 (match_operand:VDQW 2 "s_register_operand" "")]
4429 (set (match_operand:VDQW 3 "s_register_operand" "")
4430 (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VZIP2))])]
4435 ;; Note: Different operand numbering to handle tied registers correctly.
4436 (define_insn "*neon_vzip<mode>_insn"
4437 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4438 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4439 (match_operand:VDQW 3 "s_register_operand" "2")]
4441 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4442 (unspec:VDQW [(match_dup 1) (match_dup 3)]
4445 "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4446 [(set (attr "neon_type")
4447 (if_then_else (match_test "<Is_d_reg>")
4448 (const_string "neon_bp_simple")
4449 (const_string "neon_bp_3cycle")))]
4452 (define_expand "neon_vzip<mode>"
4453 [(match_operand:SI 0 "s_register_operand" "r")
4454 (match_operand:VDQW 1 "s_register_operand" "w")
4455 (match_operand:VDQW 2 "s_register_operand" "w")]
4458 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vzip<mode>_internal,
4459 operands[0], operands[1], operands[2]);
4463 (define_expand "neon_vuzp<mode>_internal"
4465 [(set (match_operand:VDQW 0 "s_register_operand" "")
4466 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4467 (match_operand:VDQW 2 "s_register_operand" "")]
4469 (set (match_operand:VDQW 3 "s_register_operand" "")
4470 (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VUZP2))])]
4475 ;; Note: Different operand numbering to handle tied registers correctly.
4476 (define_insn "*neon_vuzp<mode>_insn"
4477 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4478 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4479 (match_operand:VDQW 3 "s_register_operand" "2")]
4481 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4482 (unspec:VDQW [(match_dup 1) (match_dup 3)]
4485 "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4486 [(set (attr "neon_type")
4487 (if_then_else (match_test "<Is_d_reg>")
4488 (const_string "neon_bp_simple")
4489 (const_string "neon_bp_3cycle")))]
4492 (define_expand "neon_vuzp<mode>"
4493 [(match_operand:SI 0 "s_register_operand" "r")
4494 (match_operand:VDQW 1 "s_register_operand" "w")
4495 (match_operand:VDQW 2 "s_register_operand" "w")]
4498 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vuzp<mode>_internal,
4499 operands[0], operands[1], operands[2]);
4503 (define_expand "neon_vreinterpretv8qi<mode>"
4504 [(match_operand:V8QI 0 "s_register_operand" "")
4505 (match_operand:VDX 1 "s_register_operand" "")]
4508 neon_reinterpret (operands[0], operands[1]);
4512 (define_expand "neon_vreinterpretv4hi<mode>"
4513 [(match_operand:V4HI 0 "s_register_operand" "")
4514 (match_operand:VDX 1 "s_register_operand" "")]
4517 neon_reinterpret (operands[0], operands[1]);
4521 (define_expand "neon_vreinterpretv2si<mode>"
4522 [(match_operand:V2SI 0 "s_register_operand" "")
4523 (match_operand:VDX 1 "s_register_operand" "")]
4526 neon_reinterpret (operands[0], operands[1]);
4530 (define_expand "neon_vreinterpretv2sf<mode>"
4531 [(match_operand:V2SF 0 "s_register_operand" "")
4532 (match_operand:VDX 1 "s_register_operand" "")]
4535 neon_reinterpret (operands[0], operands[1]);
4539 (define_expand "neon_vreinterpretdi<mode>"
4540 [(match_operand:DI 0 "s_register_operand" "")
4541 (match_operand:VDX 1 "s_register_operand" "")]
4544 neon_reinterpret (operands[0], operands[1]);
4548 (define_expand "neon_vreinterpretv16qi<mode>"
4549 [(match_operand:V16QI 0 "s_register_operand" "")
4550 (match_operand:VQX 1 "s_register_operand" "")]
4553 neon_reinterpret (operands[0], operands[1]);
4557 (define_expand "neon_vreinterpretv8hi<mode>"
4558 [(match_operand:V8HI 0 "s_register_operand" "")
4559 (match_operand:VQX 1 "s_register_operand" "")]
4562 neon_reinterpret (operands[0], operands[1]);
4566 (define_expand "neon_vreinterpretv4si<mode>"
4567 [(match_operand:V4SI 0 "s_register_operand" "")
4568 (match_operand:VQX 1 "s_register_operand" "")]
4571 neon_reinterpret (operands[0], operands[1]);
4575 (define_expand "neon_vreinterpretv4sf<mode>"
4576 [(match_operand:V4SF 0 "s_register_operand" "")
4577 (match_operand:VQX 1 "s_register_operand" "")]
4580 neon_reinterpret (operands[0], operands[1]);
4584 (define_expand "neon_vreinterpretv2di<mode>"
4585 [(match_operand:V2DI 0 "s_register_operand" "")
4586 (match_operand:VQX 1 "s_register_operand" "")]
4589 neon_reinterpret (operands[0], operands[1]);
4593 (define_expand "vec_load_lanes<mode><mode>"
4594 [(set (match_operand:VDQX 0 "s_register_operand")
4595 (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_operand")]
4599 (define_insn "neon_vld1<mode>"
4600 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
4601 (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_operand" "Um")]
4604 "vld1.<V_sz_elem>\t%h0, %A1"
4605 [(set_attr "neon_type" "neon_vld1_1_2_regs")]
4608 (define_insn "neon_vld1_lane<mode>"
4609 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4610 (unspec:VDX [(match_operand:<V_elem> 1 "neon_struct_operand" "Um")
4611 (match_operand:VDX 2 "s_register_operand" "0")
4612 (match_operand:SI 3 "immediate_operand" "i")]
4616 HOST_WIDE_INT lane = INTVAL (operands[3]);
4617 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4618 if (lane < 0 || lane >= max)
4619 error ("lane out of range");
4621 return "vld1.<V_sz_elem>\t%P0, %A1";
4623 return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1";
4625 [(set (attr "neon_type")
4626 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4627 (const_string "neon_vld1_1_2_regs")
4628 (const_string "neon_vld1_vld2_lane")))]
4631 (define_insn "neon_vld1_lane<mode>"
4632 [(set (match_operand:VQX 0 "s_register_operand" "=w")
4633 (unspec:VQX [(match_operand:<V_elem> 1 "neon_struct_operand" "Um")
4634 (match_operand:VQX 2 "s_register_operand" "0")
4635 (match_operand:SI 3 "immediate_operand" "i")]
4639 HOST_WIDE_INT lane = INTVAL (operands[3]);
4640 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4641 int regno = REGNO (operands[0]);
4642 if (lane < 0 || lane >= max)
4643 error ("lane out of range");
4644 else if (lane >= max / 2)
4648 operands[3] = GEN_INT (lane);
4650 operands[0] = gen_rtx_REG (<V_HALF>mode, regno);
4652 return "vld1.<V_sz_elem>\t%P0, %A1";
4654 return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1";
4656 [(set (attr "neon_type")
4657 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4658 (const_string "neon_vld1_1_2_regs")
4659 (const_string "neon_vld1_vld2_lane")))]
4662 (define_insn "neon_vld1_dup<mode>"
4663 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4664 (vec_duplicate:VDX (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
4667 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4668 return "vld1.<V_sz_elem>\t{%P0[]}, %A1";
4670 return "vld1.<V_sz_elem>\t%h0, %A1";
4672 [(set (attr "neon_type")
4673 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4674 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4675 (const_string "neon_vld1_1_2_regs")))]
4678 (define_insn "neon_vld1_dup<mode>"
4679 [(set (match_operand:VQ 0 "s_register_operand" "=w")
4680 (vec_duplicate:VQ (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
4683 return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, %A1";
4685 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
4688 (define_insn_and_split "neon_vld1_dupv2di"
4689 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
4690 (vec_duplicate:V2DI (match_operand:DI 1 "neon_struct_operand" "Um")))]
4693 "&& reload_completed"
4696 rtx tmprtx = gen_lowpart (DImode, operands[0]);
4697 emit_insn (gen_neon_vld1_dupdi (tmprtx, operands[1]));
4698 emit_move_insn (gen_highpart (DImode, operands[0]), tmprtx );
4701 [(set_attr "length" "8")
4702 (set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
4705 (define_expand "vec_store_lanes<mode><mode>"
4706 [(set (match_operand:VDQX 0 "neon_struct_operand")
4707 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand")]
4711 (define_insn "neon_vst1<mode>"
4712 [(set (match_operand:VDQX 0 "neon_struct_operand" "=Um")
4713 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")]
4716 "vst1.<V_sz_elem>\t%h1, %A0"
4717 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
4719 (define_insn "neon_vst1_lane<mode>"
4720 [(set (match_operand:<V_elem> 0 "neon_struct_operand" "=Um")
4722 [(match_operand:VDX 1 "s_register_operand" "w")
4723 (match_operand:SI 2 "immediate_operand" "i")]
4727 HOST_WIDE_INT lane = INTVAL (operands[2]);
4728 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4729 if (lane < 0 || lane >= max)
4730 error ("lane out of range");
4732 return "vst1.<V_sz_elem>\t{%P1}, %A0";
4734 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
4736 [(set (attr "neon_type")
4737 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 1))
4738 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4739 (const_string "neon_vst1_vst2_lane")))])
4741 (define_insn "neon_vst1_lane<mode>"
4742 [(set (match_operand:<V_elem> 0 "neon_struct_operand" "=Um")
4744 [(match_operand:VQX 1 "s_register_operand" "w")
4745 (match_operand:SI 2 "immediate_operand" "i")]
4749 HOST_WIDE_INT lane = INTVAL (operands[2]);
4750 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4751 int regno = REGNO (operands[1]);
4752 if (lane < 0 || lane >= max)
4753 error ("lane out of range");
4754 else if (lane >= max / 2)
4758 operands[2] = GEN_INT (lane);
4760 operands[1] = gen_rtx_REG (<V_HALF>mode, regno);
4762 return "vst1.<V_sz_elem>\t{%P1}, %A0";
4764 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
4766 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4769 (define_expand "vec_load_lanesti<mode>"
4770 [(set (match_operand:TI 0 "s_register_operand")
4771 (unspec:TI [(match_operand:TI 1 "neon_struct_operand")
4772 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4776 (define_insn "neon_vld2<mode>"
4777 [(set (match_operand:TI 0 "s_register_operand" "=w")
4778 (unspec:TI [(match_operand:TI 1 "neon_struct_operand" "Um")
4779 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4783 if (<V_sz_elem> == 64)
4784 return "vld1.64\t%h0, %A1";
4786 return "vld2.<V_sz_elem>\t%h0, %A1";
4788 [(set (attr "neon_type")
4789 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4790 (const_string "neon_vld1_1_2_regs")
4791 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))]
4794 (define_expand "vec_load_lanesoi<mode>"
4795 [(set (match_operand:OI 0 "s_register_operand")
4796 (unspec:OI [(match_operand:OI 1 "neon_struct_operand")
4797 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4801 (define_insn "neon_vld2<mode>"
4802 [(set (match_operand:OI 0 "s_register_operand" "=w")
4803 (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um")
4804 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4807 "vld2.<V_sz_elem>\t%h0, %A1"
4808 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")])
4810 (define_insn "neon_vld2_lane<mode>"
4811 [(set (match_operand:TI 0 "s_register_operand" "=w")
4812 (unspec:TI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4813 (match_operand:TI 2 "s_register_operand" "0")
4814 (match_operand:SI 3 "immediate_operand" "i")
4815 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4819 HOST_WIDE_INT lane = INTVAL (operands[3]);
4820 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4821 int regno = REGNO (operands[0]);
4823 if (lane < 0 || lane >= max)
4824 error ("lane out of range");
4825 ops[0] = gen_rtx_REG (DImode, regno);
4826 ops[1] = gen_rtx_REG (DImode, regno + 2);
4827 ops[2] = operands[1];
4828 ops[3] = operands[3];
4829 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops);
4832 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4835 (define_insn "neon_vld2_lane<mode>"
4836 [(set (match_operand:OI 0 "s_register_operand" "=w")
4837 (unspec:OI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4838 (match_operand:OI 2 "s_register_operand" "0")
4839 (match_operand:SI 3 "immediate_operand" "i")
4840 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4844 HOST_WIDE_INT lane = INTVAL (operands[3]);
4845 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4846 int regno = REGNO (operands[0]);
4848 if (lane < 0 || lane >= max)
4849 error ("lane out of range");
4850 else if (lane >= max / 2)
4855 ops[0] = gen_rtx_REG (DImode, regno);
4856 ops[1] = gen_rtx_REG (DImode, regno + 4);
4857 ops[2] = operands[1];
4858 ops[3] = GEN_INT (lane);
4859 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops);
4862 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4865 (define_insn "neon_vld2_dup<mode>"
4866 [(set (match_operand:TI 0 "s_register_operand" "=w")
4867 (unspec:TI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4868 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4872 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4873 return "vld2.<V_sz_elem>\t{%e0[], %f0[]}, %A1";
4875 return "vld1.<V_sz_elem>\t%h0, %A1";
4877 [(set (attr "neon_type")
4878 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4879 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4880 (const_string "neon_vld1_1_2_regs")))]
4883 (define_expand "vec_store_lanesti<mode>"
4884 [(set (match_operand:TI 0 "neon_struct_operand")
4885 (unspec:TI [(match_operand:TI 1 "s_register_operand")
4886 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4890 (define_insn "neon_vst2<mode>"
4891 [(set (match_operand:TI 0 "neon_struct_operand" "=Um")
4892 (unspec:TI [(match_operand:TI 1 "s_register_operand" "w")
4893 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4897 if (<V_sz_elem> == 64)
4898 return "vst1.64\t%h1, %A0";
4900 return "vst2.<V_sz_elem>\t%h1, %A0";
4902 [(set (attr "neon_type")
4903 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4904 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4905 (const_string "neon_vst1_1_2_regs_vst2_2_regs")))]
4908 (define_expand "vec_store_lanesoi<mode>"
4909 [(set (match_operand:OI 0 "neon_struct_operand")
4910 (unspec:OI [(match_operand:OI 1 "s_register_operand")
4911 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4915 (define_insn "neon_vst2<mode>"
4916 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
4917 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4918 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4921 "vst2.<V_sz_elem>\t%h1, %A0"
4922 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]
4925 (define_insn "neon_vst2_lane<mode>"
4926 [(set (match_operand:<V_two_elem> 0 "neon_struct_operand" "=Um")
4927 (unspec:<V_two_elem>
4928 [(match_operand:TI 1 "s_register_operand" "w")
4929 (match_operand:SI 2 "immediate_operand" "i")
4930 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4934 HOST_WIDE_INT lane = INTVAL (operands[2]);
4935 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4936 int regno = REGNO (operands[1]);
4938 if (lane < 0 || lane >= max)
4939 error ("lane out of range");
4940 ops[0] = operands[0];
4941 ops[1] = gen_rtx_REG (DImode, regno);
4942 ops[2] = gen_rtx_REG (DImode, regno + 2);
4943 ops[3] = operands[2];
4944 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops);
4947 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4950 (define_insn "neon_vst2_lane<mode>"
4951 [(set (match_operand:<V_two_elem> 0 "neon_struct_operand" "=Um")
4952 (unspec:<V_two_elem>
4953 [(match_operand:OI 1 "s_register_operand" "w")
4954 (match_operand:SI 2 "immediate_operand" "i")
4955 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4959 HOST_WIDE_INT lane = INTVAL (operands[2]);
4960 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4961 int regno = REGNO (operands[1]);
4963 if (lane < 0 || lane >= max)
4964 error ("lane out of range");
4965 else if (lane >= max / 2)
4970 ops[0] = operands[0];
4971 ops[1] = gen_rtx_REG (DImode, regno);
4972 ops[2] = gen_rtx_REG (DImode, regno + 4);
4973 ops[3] = GEN_INT (lane);
4974 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops);
4977 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4980 (define_expand "vec_load_lanesei<mode>"
4981 [(set (match_operand:EI 0 "s_register_operand")
4982 (unspec:EI [(match_operand:EI 1 "neon_struct_operand")
4983 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4987 (define_insn "neon_vld3<mode>"
4988 [(set (match_operand:EI 0 "s_register_operand" "=w")
4989 (unspec:EI [(match_operand:EI 1 "neon_struct_operand" "Um")
4990 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4994 if (<V_sz_elem> == 64)
4995 return "vld1.64\t%h0, %A1";
4997 return "vld3.<V_sz_elem>\t%h0, %A1";
4999 [(set (attr "neon_type")
5000 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5001 (const_string "neon_vld1_1_2_regs")
5002 (const_string "neon_vld3_vld4")))]
5005 (define_expand "vec_load_lanesci<mode>"
5006 [(match_operand:CI 0 "s_register_operand")
5007 (match_operand:CI 1 "neon_struct_operand")
5008 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5011 emit_insn (gen_neon_vld3<mode> (operands[0], operands[1]));
5015 (define_expand "neon_vld3<mode>"
5016 [(match_operand:CI 0 "s_register_operand")
5017 (match_operand:CI 1 "neon_struct_operand")
5018 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5023 mem = adjust_address (operands[1], EImode, 0);
5024 emit_insn (gen_neon_vld3qa<mode> (operands[0], mem));
5025 mem = adjust_address (mem, EImode, GET_MODE_SIZE (EImode));
5026 emit_insn (gen_neon_vld3qb<mode> (operands[0], mem, operands[0]));
5030 (define_insn "neon_vld3qa<mode>"
5031 [(set (match_operand:CI 0 "s_register_operand" "=w")
5032 (unspec:CI [(match_operand:EI 1 "neon_struct_operand" "Um")
5033 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5037 int regno = REGNO (operands[0]);
5039 ops[0] = gen_rtx_REG (DImode, regno);
5040 ops[1] = gen_rtx_REG (DImode, regno + 4);
5041 ops[2] = gen_rtx_REG (DImode, regno + 8);
5042 ops[3] = operands[1];
5043 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops);
5046 [(set_attr "neon_type" "neon_vld3_vld4")]
5049 (define_insn "neon_vld3qb<mode>"
5050 [(set (match_operand:CI 0 "s_register_operand" "=w")
5051 (unspec:CI [(match_operand:EI 1 "neon_struct_operand" "Um")
5052 (match_operand:CI 2 "s_register_operand" "0")
5053 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5057 int regno = REGNO (operands[0]);
5059 ops[0] = gen_rtx_REG (DImode, regno + 2);
5060 ops[1] = gen_rtx_REG (DImode, regno + 6);
5061 ops[2] = gen_rtx_REG (DImode, regno + 10);
5062 ops[3] = operands[1];
5063 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops);
5066 [(set_attr "neon_type" "neon_vld3_vld4")]
5069 (define_insn "neon_vld3_lane<mode>"
5070 [(set (match_operand:EI 0 "s_register_operand" "=w")
5071 (unspec:EI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5072 (match_operand:EI 2 "s_register_operand" "0")
5073 (match_operand:SI 3 "immediate_operand" "i")
5074 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5078 HOST_WIDE_INT lane = INTVAL (operands[3]);
5079 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5080 int regno = REGNO (operands[0]);
5082 if (lane < 0 || lane >= max)
5083 error ("lane out of range");
5084 ops[0] = gen_rtx_REG (DImode, regno);
5085 ops[1] = gen_rtx_REG (DImode, regno + 2);
5086 ops[2] = gen_rtx_REG (DImode, regno + 4);
5087 ops[3] = operands[1];
5088 ops[4] = operands[3];
5089 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, %3",
5093 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5096 (define_insn "neon_vld3_lane<mode>"
5097 [(set (match_operand:CI 0 "s_register_operand" "=w")
5098 (unspec:CI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5099 (match_operand:CI 2 "s_register_operand" "0")
5100 (match_operand:SI 3 "immediate_operand" "i")
5101 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5105 HOST_WIDE_INT lane = INTVAL (operands[3]);
5106 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5107 int regno = REGNO (operands[0]);
5109 if (lane < 0 || lane >= max)
5110 error ("lane out of range");
5111 else if (lane >= max / 2)
5116 ops[0] = gen_rtx_REG (DImode, regno);
5117 ops[1] = gen_rtx_REG (DImode, regno + 4);
5118 ops[2] = gen_rtx_REG (DImode, regno + 8);
5119 ops[3] = operands[1];
5120 ops[4] = GEN_INT (lane);
5121 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, %3",
5125 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5128 (define_insn "neon_vld3_dup<mode>"
5129 [(set (match_operand:EI 0 "s_register_operand" "=w")
5130 (unspec:EI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5131 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5135 if (GET_MODE_NUNITS (<MODE>mode) > 1)
5137 int regno = REGNO (operands[0]);
5139 ops[0] = gen_rtx_REG (DImode, regno);
5140 ops[1] = gen_rtx_REG (DImode, regno + 2);
5141 ops[2] = gen_rtx_REG (DImode, regno + 4);
5142 ops[3] = operands[1];
5143 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[], %P1[], %P2[]}, %3", ops);
5147 return "vld1.<V_sz_elem>\t%h0, %A1";
5149 [(set (attr "neon_type")
5150 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
5151 (const_string "neon_vld3_vld4_all_lanes")
5152 (const_string "neon_vld1_1_2_regs")))])
5154 (define_expand "vec_store_lanesei<mode>"
5155 [(set (match_operand:EI 0 "neon_struct_operand")
5156 (unspec:EI [(match_operand:EI 1 "s_register_operand")
5157 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5161 (define_insn "neon_vst3<mode>"
5162 [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5163 (unspec:EI [(match_operand:EI 1 "s_register_operand" "w")
5164 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5168 if (<V_sz_elem> == 64)
5169 return "vst1.64\t%h1, %A0";
5171 return "vst3.<V_sz_elem>\t%h1, %A0";
5173 [(set (attr "neon_type")
5174 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5175 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
5176 (const_string "neon_vst2_4_regs_vst3_vst4")))])
5178 (define_expand "vec_store_lanesci<mode>"
5179 [(match_operand:CI 0 "neon_struct_operand")
5180 (match_operand:CI 1 "s_register_operand")
5181 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5184 emit_insn (gen_neon_vst3<mode> (operands[0], operands[1]));
5188 (define_expand "neon_vst3<mode>"
5189 [(match_operand:CI 0 "neon_struct_operand")
5190 (match_operand:CI 1 "s_register_operand")
5191 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5196 mem = adjust_address (operands[0], EImode, 0);
5197 emit_insn (gen_neon_vst3qa<mode> (mem, operands[1]));
5198 mem = adjust_address (mem, EImode, GET_MODE_SIZE (EImode));
5199 emit_insn (gen_neon_vst3qb<mode> (mem, operands[1]));
5203 (define_insn "neon_vst3qa<mode>"
5204 [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5205 (unspec:EI [(match_operand:CI 1 "s_register_operand" "w")
5206 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5210 int regno = REGNO (operands[1]);
5212 ops[0] = operands[0];
5213 ops[1] = gen_rtx_REG (DImode, regno);
5214 ops[2] = gen_rtx_REG (DImode, regno + 4);
5215 ops[3] = gen_rtx_REG (DImode, regno + 8);
5216 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops);
5219 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5222 (define_insn "neon_vst3qb<mode>"
5223 [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5224 (unspec:EI [(match_operand:CI 1 "s_register_operand" "w")
5225 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5229 int regno = REGNO (operands[1]);
5231 ops[0] = operands[0];
5232 ops[1] = gen_rtx_REG (DImode, regno + 2);
5233 ops[2] = gen_rtx_REG (DImode, regno + 6);
5234 ops[3] = gen_rtx_REG (DImode, regno + 10);
5235 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops);
5238 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5241 (define_insn "neon_vst3_lane<mode>"
5242 [(set (match_operand:<V_three_elem> 0 "neon_struct_operand" "=Um")
5243 (unspec:<V_three_elem>
5244 [(match_operand:EI 1 "s_register_operand" "w")
5245 (match_operand:SI 2 "immediate_operand" "i")
5246 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5250 HOST_WIDE_INT lane = INTVAL (operands[2]);
5251 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5252 int regno = REGNO (operands[1]);
5254 if (lane < 0 || lane >= max)
5255 error ("lane out of range");
5256 ops[0] = operands[0];
5257 ops[1] = gen_rtx_REG (DImode, regno);
5258 ops[2] = gen_rtx_REG (DImode, regno + 2);
5259 ops[3] = gen_rtx_REG (DImode, regno + 4);
5260 ops[4] = operands[2];
5261 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, %0",
5265 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5268 (define_insn "neon_vst3_lane<mode>"
5269 [(set (match_operand:<V_three_elem> 0 "neon_struct_operand" "=Um")
5270 (unspec:<V_three_elem>
5271 [(match_operand:CI 1 "s_register_operand" "w")
5272 (match_operand:SI 2 "immediate_operand" "i")
5273 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5277 HOST_WIDE_INT lane = INTVAL (operands[2]);
5278 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5279 int regno = REGNO (operands[1]);
5281 if (lane < 0 || lane >= max)
5282 error ("lane out of range");
5283 else if (lane >= max / 2)
5288 ops[0] = operands[0];
5289 ops[1] = gen_rtx_REG (DImode, regno);
5290 ops[2] = gen_rtx_REG (DImode, regno + 4);
5291 ops[3] = gen_rtx_REG (DImode, regno + 8);
5292 ops[4] = GEN_INT (lane);
5293 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, %0",
5297 [(set_attr "neon_type" "neon_vst3_vst4_lane")])
5299 (define_expand "vec_load_lanesoi<mode>"
5300 [(set (match_operand:OI 0 "s_register_operand")
5301 (unspec:OI [(match_operand:OI 1 "neon_struct_operand")
5302 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5306 (define_insn "neon_vld4<mode>"
5307 [(set (match_operand:OI 0 "s_register_operand" "=w")
5308 (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um")
5309 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5313 if (<V_sz_elem> == 64)
5314 return "vld1.64\t%h0, %A1";
5316 return "vld4.<V_sz_elem>\t%h0, %A1";
5318 [(set (attr "neon_type")
5319 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5320 (const_string "neon_vld1_1_2_regs")
5321 (const_string "neon_vld3_vld4")))]
5324 (define_expand "vec_load_lanesxi<mode>"
5325 [(match_operand:XI 0 "s_register_operand")
5326 (match_operand:XI 1 "neon_struct_operand")
5327 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5330 emit_insn (gen_neon_vld4<mode> (operands[0], operands[1]));
5334 (define_expand "neon_vld4<mode>"
5335 [(match_operand:XI 0 "s_register_operand")
5336 (match_operand:XI 1 "neon_struct_operand")
5337 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5342 mem = adjust_address (operands[1], OImode, 0);
5343 emit_insn (gen_neon_vld4qa<mode> (operands[0], mem));
5344 mem = adjust_address (mem, OImode, GET_MODE_SIZE (OImode));
5345 emit_insn (gen_neon_vld4qb<mode> (operands[0], mem, operands[0]));
5349 (define_insn "neon_vld4qa<mode>"
5350 [(set (match_operand:XI 0 "s_register_operand" "=w")
5351 (unspec:XI [(match_operand:OI 1 "neon_struct_operand" "Um")
5352 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5356 int regno = REGNO (operands[0]);
5358 ops[0] = gen_rtx_REG (DImode, regno);
5359 ops[1] = gen_rtx_REG (DImode, regno + 4);
5360 ops[2] = gen_rtx_REG (DImode, regno + 8);
5361 ops[3] = gen_rtx_REG (DImode, regno + 12);
5362 ops[4] = operands[1];
5363 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops);
5366 [(set_attr "neon_type" "neon_vld3_vld4")]
5369 (define_insn "neon_vld4qb<mode>"
5370 [(set (match_operand:XI 0 "s_register_operand" "=w")
5371 (unspec:XI [(match_operand:OI 1 "neon_struct_operand" "Um")
5372 (match_operand:XI 2 "s_register_operand" "0")
5373 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5377 int regno = REGNO (operands[0]);
5379 ops[0] = gen_rtx_REG (DImode, regno + 2);
5380 ops[1] = gen_rtx_REG (DImode, regno + 6);
5381 ops[2] = gen_rtx_REG (DImode, regno + 10);
5382 ops[3] = gen_rtx_REG (DImode, regno + 14);
5383 ops[4] = operands[1];
5384 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops);
5387 [(set_attr "neon_type" "neon_vld3_vld4")]
5390 (define_insn "neon_vld4_lane<mode>"
5391 [(set (match_operand:OI 0 "s_register_operand" "=w")
5392 (unspec:OI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5393 (match_operand:OI 2 "s_register_operand" "0")
5394 (match_operand:SI 3 "immediate_operand" "i")
5395 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5399 HOST_WIDE_INT lane = INTVAL (operands[3]);
5400 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5401 int regno = REGNO (operands[0]);
5403 if (lane < 0 || lane >= max)
5404 error ("lane out of range");
5405 ops[0] = gen_rtx_REG (DImode, regno);
5406 ops[1] = gen_rtx_REG (DImode, regno + 2);
5407 ops[2] = gen_rtx_REG (DImode, regno + 4);
5408 ops[3] = gen_rtx_REG (DImode, regno + 6);
5409 ops[4] = operands[1];
5410 ops[5] = operands[3];
5411 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, %A4",
5415 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5418 (define_insn "neon_vld4_lane<mode>"
5419 [(set (match_operand:XI 0 "s_register_operand" "=w")
5420 (unspec:XI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5421 (match_operand:XI 2 "s_register_operand" "0")
5422 (match_operand:SI 3 "immediate_operand" "i")
5423 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5427 HOST_WIDE_INT lane = INTVAL (operands[3]);
5428 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5429 int regno = REGNO (operands[0]);
5431 if (lane < 0 || lane >= max)
5432 error ("lane out of range");
5433 else if (lane >= max / 2)
5438 ops[0] = gen_rtx_REG (DImode, regno);
5439 ops[1] = gen_rtx_REG (DImode, regno + 4);
5440 ops[2] = gen_rtx_REG (DImode, regno + 8);
5441 ops[3] = gen_rtx_REG (DImode, regno + 12);
5442 ops[4] = operands[1];
5443 ops[5] = GEN_INT (lane);
5444 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, %A4",
5448 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5451 (define_insn "neon_vld4_dup<mode>"
5452 [(set (match_operand:OI 0 "s_register_operand" "=w")
5453 (unspec:OI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5454 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5458 if (GET_MODE_NUNITS (<MODE>mode) > 1)
5460 int regno = REGNO (operands[0]);
5462 ops[0] = gen_rtx_REG (DImode, regno);
5463 ops[1] = gen_rtx_REG (DImode, regno + 2);
5464 ops[2] = gen_rtx_REG (DImode, regno + 4);
5465 ops[3] = gen_rtx_REG (DImode, regno + 6);
5466 ops[4] = operands[1];
5467 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[], %P1[], %P2[], %P3[]}, %A4",
5472 return "vld1.<V_sz_elem>\t%h0, %A1";
5474 [(set (attr "neon_type")
5475 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
5476 (const_string "neon_vld3_vld4_all_lanes")
5477 (const_string "neon_vld1_1_2_regs")))]
5480 (define_expand "vec_store_lanesoi<mode>"
5481 [(set (match_operand:OI 0 "neon_struct_operand")
5482 (unspec:OI [(match_operand:OI 1 "s_register_operand")
5483 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5487 (define_insn "neon_vst4<mode>"
5488 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5489 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
5490 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5494 if (<V_sz_elem> == 64)
5495 return "vst1.64\t%h1, %A0";
5497 return "vst4.<V_sz_elem>\t%h1, %A0";
5499 [(set (attr "neon_type")
5500 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5501 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
5502 (const_string "neon_vst2_4_regs_vst3_vst4")))]
5505 (define_expand "vec_store_lanesxi<mode>"
5506 [(match_operand:XI 0 "neon_struct_operand")
5507 (match_operand:XI 1 "s_register_operand")
5508 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5511 emit_insn (gen_neon_vst4<mode> (operands[0], operands[1]));
5515 (define_expand "neon_vst4<mode>"
5516 [(match_operand:XI 0 "neon_struct_operand")
5517 (match_operand:XI 1 "s_register_operand")
5518 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5523 mem = adjust_address (operands[0], OImode, 0);
5524 emit_insn (gen_neon_vst4qa<mode> (mem, operands[1]));
5525 mem = adjust_address (mem, OImode, GET_MODE_SIZE (OImode));
5526 emit_insn (gen_neon_vst4qb<mode> (mem, operands[1]));
5530 (define_insn "neon_vst4qa<mode>"
5531 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5532 (unspec:OI [(match_operand:XI 1 "s_register_operand" "w")
5533 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5537 int regno = REGNO (operands[1]);
5539 ops[0] = operands[0];
5540 ops[1] = gen_rtx_REG (DImode, regno);
5541 ops[2] = gen_rtx_REG (DImode, regno + 4);
5542 ops[3] = gen_rtx_REG (DImode, regno + 8);
5543 ops[4] = gen_rtx_REG (DImode, regno + 12);
5544 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops);
5547 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5550 (define_insn "neon_vst4qb<mode>"
5551 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5552 (unspec:OI [(match_operand:XI 1 "s_register_operand" "w")
5553 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5557 int regno = REGNO (operands[1]);
5559 ops[0] = operands[0];
5560 ops[1] = gen_rtx_REG (DImode, regno + 2);
5561 ops[2] = gen_rtx_REG (DImode, regno + 6);
5562 ops[3] = gen_rtx_REG (DImode, regno + 10);
5563 ops[4] = gen_rtx_REG (DImode, regno + 14);
5564 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops);
5567 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5570 (define_insn "neon_vst4_lane<mode>"
5571 [(set (match_operand:<V_four_elem> 0 "neon_struct_operand" "=Um")
5572 (unspec:<V_four_elem>
5573 [(match_operand:OI 1 "s_register_operand" "w")
5574 (match_operand:SI 2 "immediate_operand" "i")
5575 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5579 HOST_WIDE_INT lane = INTVAL (operands[2]);
5580 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5581 int regno = REGNO (operands[1]);
5583 if (lane < 0 || lane >= max)
5584 error ("lane out of range");
5585 ops[0] = operands[0];
5586 ops[1] = gen_rtx_REG (DImode, regno);
5587 ops[2] = gen_rtx_REG (DImode, regno + 2);
5588 ops[3] = gen_rtx_REG (DImode, regno + 4);
5589 ops[4] = gen_rtx_REG (DImode, regno + 6);
5590 ops[5] = operands[2];
5591 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, %A0",
5595 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5598 (define_insn "neon_vst4_lane<mode>"
5599 [(set (match_operand:<V_four_elem> 0 "neon_struct_operand" "=Um")
5600 (unspec:<V_four_elem>
5601 [(match_operand:XI 1 "s_register_operand" "w")
5602 (match_operand:SI 2 "immediate_operand" "i")
5603 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5607 HOST_WIDE_INT lane = INTVAL (operands[2]);
5608 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5609 int regno = REGNO (operands[1]);
5611 if (lane < 0 || lane >= max)
5612 error ("lane out of range");
5613 else if (lane >= max / 2)
5618 ops[0] = operands[0];
5619 ops[1] = gen_rtx_REG (DImode, regno);
5620 ops[2] = gen_rtx_REG (DImode, regno + 4);
5621 ops[3] = gen_rtx_REG (DImode, regno + 8);
5622 ops[4] = gen_rtx_REG (DImode, regno + 12);
5623 ops[5] = GEN_INT (lane);
5624 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, %A0",
5628 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5631 (define_expand "neon_vand<mode>"
5632 [(match_operand:VDQX 0 "s_register_operand" "")
5633 (match_operand:VDQX 1 "s_register_operand" "")
5634 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5635 (match_operand:SI 3 "immediate_operand" "")]
5638 emit_insn (gen_and<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5642 (define_expand "neon_vorr<mode>"
5643 [(match_operand:VDQX 0 "s_register_operand" "")
5644 (match_operand:VDQX 1 "s_register_operand" "")
5645 (match_operand:VDQX 2 "neon_logic_op2" "")
5646 (match_operand:SI 3 "immediate_operand" "")]
5649 emit_insn (gen_ior<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5653 (define_expand "neon_veor<mode>"
5654 [(match_operand:VDQX 0 "s_register_operand" "")
5655 (match_operand:VDQX 1 "s_register_operand" "")
5656 (match_operand:VDQX 2 "s_register_operand" "")
5657 (match_operand:SI 3 "immediate_operand" "")]
5660 emit_insn (gen_xor<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5664 (define_expand "neon_vbic<mode>"
5665 [(match_operand:VDQX 0 "s_register_operand" "")
5666 (match_operand:VDQX 1 "s_register_operand" "")
5667 (match_operand:VDQX 2 "neon_logic_op2" "")
5668 (match_operand:SI 3 "immediate_operand" "")]
5671 emit_insn (gen_bic<mode>3_neon (operands[0], operands[1], operands[2]));
5675 (define_expand "neon_vorn<mode>"
5676 [(match_operand:VDQX 0 "s_register_operand" "")
5677 (match_operand:VDQX 1 "s_register_operand" "")
5678 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5679 (match_operand:SI 3 "immediate_operand" "")]
5682 emit_insn (gen_orn<mode>3_neon (operands[0], operands[1], operands[2]));
5686 (define_insn "neon_vec_unpack<US>_lo_<mode>"
5687 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5688 (SE:<V_unpack> (vec_select:<V_HALF>
5689 (match_operand:VU 1 "register_operand" "w")
5690 (match_operand:VU 2 "vect_par_constant_low" ""))))]
5691 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5692 "vmovl.<US><V_sz_elem> %q0, %e1"
5693 [(set_attr "neon_type" "neon_shift_1")]
5696 (define_insn "neon_vec_unpack<US>_hi_<mode>"
5697 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5698 (SE:<V_unpack> (vec_select:<V_HALF>
5699 (match_operand:VU 1 "register_operand" "w")
5700 (match_operand:VU 2 "vect_par_constant_high" ""))))]
5701 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5702 "vmovl.<US><V_sz_elem> %q0, %f1"
5703 [(set_attr "neon_type" "neon_shift_1")]
5706 (define_expand "vec_unpack<US>_hi_<mode>"
5707 [(match_operand:<V_unpack> 0 "register_operand" "")
5708 (SE:<V_unpack> (match_operand:VU 1 "register_operand"))]
5709 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5711 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5714 for (i = 0; i < (<V_mode_nunits>/2); i++)
5715 RTVEC_ELT (v, i) = GEN_INT ((<V_mode_nunits>/2) + i);
5717 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5718 emit_insn (gen_neon_vec_unpack<US>_hi_<mode> (operands[0],
5725 (define_expand "vec_unpack<US>_lo_<mode>"
5726 [(match_operand:<V_unpack> 0 "register_operand" "")
5727 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))]
5728 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5730 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5733 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5734 RTVEC_ELT (v, i) = GEN_INT (i);
5735 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5736 emit_insn (gen_neon_vec_unpack<US>_lo_<mode> (operands[0],
5743 (define_insn "neon_vec_<US>mult_lo_<mode>"
5744 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5745 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5746 (match_operand:VU 1 "register_operand" "w")
5747 (match_operand:VU 2 "vect_par_constant_low" "")))
5748 (SE:<V_unpack> (vec_select:<V_HALF>
5749 (match_operand:VU 3 "register_operand" "w")
5751 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5752 "vmull.<US><V_sz_elem> %q0, %e1, %e3"
5753 [(set_attr "neon_type" "neon_shift_1")]
5756 (define_expand "vec_widen_<US>mult_lo_<mode>"
5757 [(match_operand:<V_unpack> 0 "register_operand" "")
5758 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5759 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5760 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5762 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5765 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5766 RTVEC_ELT (v, i) = GEN_INT (i);
5767 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5769 emit_insn (gen_neon_vec_<US>mult_lo_<mode> (operands[0],
5777 (define_insn "neon_vec_<US>mult_hi_<mode>"
5778 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5779 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5780 (match_operand:VU 1 "register_operand" "w")
5781 (match_operand:VU 2 "vect_par_constant_high" "")))
5782 (SE:<V_unpack> (vec_select:<V_HALF>
5783 (match_operand:VU 3 "register_operand" "w")
5785 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5786 "vmull.<US><V_sz_elem> %q0, %f1, %f3"
5787 [(set_attr "neon_type" "neon_shift_1")]
5790 (define_expand "vec_widen_<US>mult_hi_<mode>"
5791 [(match_operand:<V_unpack> 0 "register_operand" "")
5792 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5793 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5794 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5796 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5799 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5800 RTVEC_ELT (v, i) = GEN_INT (<V_mode_nunits>/2 + i);
5801 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5803 emit_insn (gen_neon_vec_<US>mult_hi_<mode> (operands[0],
5812 (define_insn "neon_vec_<US>shiftl_<mode>"
5813 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5814 (SE:<V_widen> (ashift:VW (match_operand:VW 1 "register_operand" "w")
5815 (match_operand:<V_innermode> 2 "const_neon_scalar_shift_amount_operand" ""))))]
5818 return "vshll.<US><V_sz_elem> %q0, %P1, %2";
5820 [(set_attr "neon_type" "neon_shift_1")]
5823 (define_expand "vec_widen_<US>shiftl_lo_<mode>"
5824 [(match_operand:<V_unpack> 0 "register_operand" "")
5825 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5826 (match_operand:SI 2 "immediate_operand" "i")]
5827 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5829 emit_insn (gen_neon_vec_<US>shiftl_<V_half> (operands[0],
5830 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode, 0),
5836 (define_expand "vec_widen_<US>shiftl_hi_<mode>"
5837 [(match_operand:<V_unpack> 0 "register_operand" "")
5838 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5839 (match_operand:SI 2 "immediate_operand" "i")]
5840 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5842 emit_insn (gen_neon_vec_<US>shiftl_<V_half> (operands[0],
5843 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode,
5844 GET_MODE_SIZE (<V_HALF>mode)),
5850 ;; Vectorize for non-neon-quad case
5851 (define_insn "neon_unpack<US>_<mode>"
5852 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5853 (SE:<V_widen> (match_operand:VDI 1 "register_operand" "w")))]
5855 "vmovl.<US><V_sz_elem> %q0, %P1"
5856 [(set_attr "neon_type" "neon_shift_1")]
5859 (define_expand "vec_unpack<US>_lo_<mode>"
5860 [(match_operand:<V_double_width> 0 "register_operand" "")
5861 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5864 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5865 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5866 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5872 (define_expand "vec_unpack<US>_hi_<mode>"
5873 [(match_operand:<V_double_width> 0 "register_operand" "")
5874 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5877 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5878 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5879 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5885 (define_insn "neon_vec_<US>mult_<mode>"
5886 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5887 (mult:<V_widen> (SE:<V_widen>
5888 (match_operand:VDI 1 "register_operand" "w"))
5890 (match_operand:VDI 2 "register_operand" "w"))))]
5892 "vmull.<US><V_sz_elem> %q0, %P1, %P2"
5893 [(set_attr "neon_type" "neon_shift_1")]
5896 (define_expand "vec_widen_<US>mult_hi_<mode>"
5897 [(match_operand:<V_double_width> 0 "register_operand" "")
5898 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5899 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5902 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5903 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5904 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5911 (define_expand "vec_widen_<US>mult_lo_<mode>"
5912 [(match_operand:<V_double_width> 0 "register_operand" "")
5913 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5914 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5917 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5918 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5919 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5926 (define_expand "vec_widen_<US>shiftl_hi_<mode>"
5927 [(match_operand:<V_double_width> 0 "register_operand" "")
5928 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5929 (match_operand:SI 2 "immediate_operand" "i")]
5932 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5933 emit_insn (gen_neon_vec_<US>shiftl_<mode> (tmpreg, operands[1], operands[2]));
5934 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5940 (define_expand "vec_widen_<US>shiftl_lo_<mode>"
5941 [(match_operand:<V_double_width> 0 "register_operand" "")
5942 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5943 (match_operand:SI 2 "immediate_operand" "i")]
5946 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5947 emit_insn (gen_neon_vec_<US>shiftl_<mode> (tmpreg, operands[1], operands[2]));
5948 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5954 ; FIXME: These instruction patterns can't be used safely in big-endian mode
5955 ; because the ordering of vector elements in Q registers is different from what
5956 ; the semantics of the instructions require.
5958 (define_insn "vec_pack_trunc_<mode>"
5959 [(set (match_operand:<V_narrow_pack> 0 "register_operand" "=&w")
5960 (vec_concat:<V_narrow_pack>
5961 (truncate:<V_narrow>
5962 (match_operand:VN 1 "register_operand" "w"))
5963 (truncate:<V_narrow>
5964 (match_operand:VN 2 "register_operand" "w"))))]
5965 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5966 "vmovn.i<V_sz_elem>\t%e0, %q1\;vmovn.i<V_sz_elem>\t%f0, %q2"
5967 [(set_attr "neon_type" "neon_shift_1")
5968 (set_attr "length" "8")]
5971 ;; For the non-quad case.
5972 (define_insn "neon_vec_pack_trunc_<mode>"
5973 [(set (match_operand:<V_narrow> 0 "register_operand" "=w")
5974 (truncate:<V_narrow> (match_operand:VN 1 "register_operand" "w")))]
5975 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5976 "vmovn.i<V_sz_elem>\t%P0, %q1"
5977 [(set_attr "neon_type" "neon_shift_1")]
5980 (define_expand "vec_pack_trunc_<mode>"
5981 [(match_operand:<V_narrow_pack> 0 "register_operand" "")
5982 (match_operand:VSHFT 1 "register_operand" "")
5983 (match_operand:VSHFT 2 "register_operand")]
5984 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5986 rtx tempreg = gen_reg_rtx (<V_DOUBLE>mode);
5988 emit_insn (gen_move_lo_quad_<V_double> (tempreg, operands[1]));
5989 emit_insn (gen_move_hi_quad_<V_double> (tempreg, operands[2]));
5990 emit_insn (gen_neon_vec_pack_trunc_<V_double> (operands[0], tempreg));
5994 (define_insn "neon_vabd<mode>_2"
5995 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
5996 (abs:VDQ (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
5997 (match_operand:VDQ 2 "s_register_operand" "w"))))]
5998 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
5999 "vabd.<V_s_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2"
6000 [(set (attr "neon_type")
6001 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
6002 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
6003 (const_string "neon_fp_vadd_ddd_vabs_dd")
6004 (const_string "neon_fp_vadd_qqq_vabs_qq"))
6005 (const_string "neon_int_5")))]
6008 (define_insn "neon_vabd<mode>_3"
6009 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
6010 (abs:VDQ (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
6011 (match_operand:VDQ 2 "s_register_operand" "w")]
6013 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
6014 "vabd.<V_if_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2"
6015 [(set (attr "neon_type")
6016 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
6017 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
6018 (const_string "neon_fp_vadd_ddd_vabs_dd")
6019 (const_string "neon_fp_vadd_qqq_vabs_qq"))
6020 (const_string "neon_int_5")))]
6023 ;; Copy from core-to-neon regs, then extend, not vice-versa
6026 [(set (match_operand:DI 0 "s_register_operand" "")
6027 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
6028 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6029 [(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1)))
6030 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 32)))]
6032 operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0]));
6036 [(set (match_operand:DI 0 "s_register_operand" "")
6037 (sign_extend:DI (match_operand:HI 1 "s_register_operand" "")))]
6038 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6039 [(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1)))
6040 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
6042 operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0]));
6046 [(set (match_operand:DI 0 "s_register_operand" "")
6047 (sign_extend:DI (match_operand:QI 1 "s_register_operand" "")))]
6048 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6049 [(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1)))
6050 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
6052 operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0]));
6056 [(set (match_operand:DI 0 "s_register_operand" "")
6057 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
6058 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6059 [(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1)))
6060 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 32)))]
6062 operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0]));
6066 [(set (match_operand:DI 0 "s_register_operand" "")
6067 (zero_extend:DI (match_operand:HI 1 "s_register_operand" "")))]
6068 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6069 [(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1)))
6070 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
6072 operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0]));
6076 [(set (match_operand:DI 0 "s_register_operand" "")
6077 (zero_extend:DI (match_operand:QI 1 "s_register_operand" "")))]
6078 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6079 [(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1)))
6080 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
6082 operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0]));