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,*,*,arlo_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" "*,*,*,*,*,*,arlo_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_perm_struct_or_reg_operand")
245 (unspec:VDQX [(match_operand:VDQX 1 "neon_perm_struct_or_reg_operand")]
246 UNSPEC_MISALIGNED_ACCESS))]
247 "TARGET_NEON && !BYTES_BIG_ENDIAN"
249 /* This pattern is not permitted to fail during expansion: if both arguments
250 are non-registers (e.g. memory := constant, which can be created by the
251 auto-vectorizer), force operand 1 into a register. */
252 if (!s_register_operand (operands[0], <MODE>mode)
253 && !s_register_operand (operands[1], <MODE>mode))
254 operands[1] = force_reg (<MODE>mode, operands[1]);
257 (define_insn "*movmisalign<mode>_neon_store"
258 [(set (match_operand:VDX 0 "neon_permissive_struct_operand" "=Um")
259 (unspec:VDX [(match_operand:VDX 1 "s_register_operand" " w")]
260 UNSPEC_MISALIGNED_ACCESS))]
261 "TARGET_NEON && !BYTES_BIG_ENDIAN"
262 "vst1.<V_sz_elem>\t{%P1}, %A0"
263 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
265 (define_insn "*movmisalign<mode>_neon_load"
266 [(set (match_operand:VDX 0 "s_register_operand" "=w")
267 (unspec:VDX [(match_operand:VDX 1 "neon_permissive_struct_operand"
269 UNSPEC_MISALIGNED_ACCESS))]
270 "TARGET_NEON && !BYTES_BIG_ENDIAN"
271 "vld1.<V_sz_elem>\t{%P0}, %A1"
272 [(set_attr "neon_type" "neon_vld1_1_2_regs")])
274 (define_insn "*movmisalign<mode>_neon_store"
275 [(set (match_operand:VQX 0 "neon_permissive_struct_operand" "=Um")
276 (unspec:VQX [(match_operand:VQX 1 "s_register_operand" " w")]
277 UNSPEC_MISALIGNED_ACCESS))]
278 "TARGET_NEON && !BYTES_BIG_ENDIAN"
279 "vst1.<V_sz_elem>\t{%q1}, %A0"
280 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
282 (define_insn "*movmisalign<mode>_neon_load"
283 [(set (match_operand:VQX 0 "s_register_operand" "=w")
284 (unspec:VQX [(match_operand:VQX 1 "neon_permissive_struct_operand"
286 UNSPEC_MISALIGNED_ACCESS))]
287 "TARGET_NEON && !BYTES_BIG_ENDIAN"
288 "vld1.<V_sz_elem>\t{%q0}, %A1"
289 [(set_attr "neon_type" "neon_vld1_1_2_regs")])
291 (define_insn "vec_set<mode>_internal"
292 [(set (match_operand:VD 0 "s_register_operand" "=w,w")
295 (match_operand:<V_elem> 1 "nonimmediate_operand" "Um,r"))
296 (match_operand:VD 3 "s_register_operand" "0,0")
297 (match_operand:SI 2 "immediate_operand" "i,i")))]
300 int elt = ffs ((int) INTVAL (operands[2])) - 1;
301 if (BYTES_BIG_ENDIAN)
302 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
303 operands[2] = GEN_INT (elt);
305 if (which_alternative == 0)
306 return "vld1.<V_sz_elem>\t{%P0[%c2]}, %A1";
308 return "vmov.<V_sz_elem>\t%P0[%c2], %1";
310 [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")])
312 (define_insn "vec_set<mode>_internal"
313 [(set (match_operand:VQ 0 "s_register_operand" "=w,w")
316 (match_operand:<V_elem> 1 "nonimmediate_operand" "Um,r"))
317 (match_operand:VQ 3 "s_register_operand" "0,0")
318 (match_operand:SI 2 "immediate_operand" "i,i")))]
321 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
322 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
323 int elt = elem % half_elts;
324 int hi = (elem / half_elts) * 2;
325 int regno = REGNO (operands[0]);
327 if (BYTES_BIG_ENDIAN)
328 elt = half_elts - 1 - elt;
330 operands[0] = gen_rtx_REG (<V_HALF>mode, regno + hi);
331 operands[2] = GEN_INT (elt);
333 if (which_alternative == 0)
334 return "vld1.<V_sz_elem>\t{%P0[%c2]}, %A1";
336 return "vmov.<V_sz_elem>\t%P0[%c2], %1";
338 [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")]
341 (define_insn "vec_setv2di_internal"
342 [(set (match_operand:V2DI 0 "s_register_operand" "=w,w")
345 (match_operand:DI 1 "nonimmediate_operand" "Um,r"))
346 (match_operand:V2DI 3 "s_register_operand" "0,0")
347 (match_operand:SI 2 "immediate_operand" "i,i")))]
350 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
351 int regno = REGNO (operands[0]) + 2 * elem;
353 operands[0] = gen_rtx_REG (DImode, regno);
355 if (which_alternative == 0)
356 return "vld1.64\t%P0, %A1";
358 return "vmov\t%P0, %Q1, %R1";
360 [(set_attr "neon_type" "neon_vld1_1_2_regs,neon_mcr_2_mcrr")]
363 (define_expand "vec_set<mode>"
364 [(match_operand:VDQ 0 "s_register_operand" "")
365 (match_operand:<V_elem> 1 "s_register_operand" "")
366 (match_operand:SI 2 "immediate_operand" "")]
369 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
370 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
371 GEN_INT (elem), operands[0]));
375 (define_insn "vec_extract<mode>"
376 [(set (match_operand:<V_elem> 0 "nonimmediate_operand" "=Um,r")
378 (match_operand:VD 1 "s_register_operand" "w,w")
379 (parallel [(match_operand:SI 2 "immediate_operand" "i,i")])))]
382 if (BYTES_BIG_ENDIAN)
384 int elt = INTVAL (operands[2]);
385 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
386 operands[2] = GEN_INT (elt);
389 if (which_alternative == 0)
390 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
392 return "vmov.<V_uf_sclr>\t%0, %P1[%c2]";
394 [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_bp_simple")]
397 (define_insn "vec_extract<mode>"
398 [(set (match_operand:<V_elem> 0 "nonimmediate_operand" "=Um,r")
400 (match_operand:VQ 1 "s_register_operand" "w,w")
401 (parallel [(match_operand:SI 2 "immediate_operand" "i,i")])))]
404 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
405 int elt = INTVAL (operands[2]) % half_elts;
406 int hi = (INTVAL (operands[2]) / half_elts) * 2;
407 int regno = REGNO (operands[1]);
409 if (BYTES_BIG_ENDIAN)
410 elt = half_elts - 1 - elt;
412 operands[1] = gen_rtx_REG (<V_HALF>mode, regno + hi);
413 operands[2] = GEN_INT (elt);
415 if (which_alternative == 0)
416 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
418 return "vmov.<V_uf_sclr>\t%0, %P1[%c2]";
420 [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_bp_simple")]
423 (define_insn "vec_extractv2di"
424 [(set (match_operand:DI 0 "nonimmediate_operand" "=Um,r")
426 (match_operand:V2DI 1 "s_register_operand" "w,w")
427 (parallel [(match_operand:SI 2 "immediate_operand" "i,i")])))]
430 int regno = REGNO (operands[1]) + 2 * INTVAL (operands[2]);
432 operands[1] = gen_rtx_REG (DImode, regno);
434 if (which_alternative == 0)
435 return "vst1.64\t{%P1}, %A0 @ v2di";
437 return "vmov\t%Q0, %R0, %P1 @ v2di";
439 [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_int_1")]
442 (define_expand "vec_init<mode>"
443 [(match_operand:VDQ 0 "s_register_operand" "")
444 (match_operand 1 "" "")]
447 neon_expand_vector_init (operands[0], operands[1]);
451 ;; Doubleword and quadword arithmetic.
453 ;; NOTE: some other instructions also support 64-bit integer
454 ;; element size, which we could potentially use for "long long" operations.
456 (define_insn "*add<mode>3_neon"
457 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
458 (plus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
459 (match_operand:VDQ 2 "s_register_operand" "w")))]
460 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
461 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
462 [(set (attr "neon_type")
463 (if_then_else (match_test "<Is_float_mode>")
464 (if_then_else (match_test "<Is_d_reg>")
465 (const_string "neon_fp_vadd_ddd_vabs_dd")
466 (const_string "neon_fp_vadd_qqq_vabs_qq"))
467 (const_string "neon_int_1")))]
470 (define_insn "adddi3_neon"
471 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w,?&r,?&r,?&r")
472 (plus:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,w,r,0,r")
473 (match_operand:DI 2 "arm_adddi_operand" "w,r,0,w,r,Dd,Dd")))
474 (clobber (reg:CC CC_REGNUM))]
477 switch (which_alternative)
479 case 0: /* fall through */
480 case 3: return "vadd.i64\t%P0, %P1, %P2";
486 default: gcc_unreachable ();
489 [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1,*,*,*")
490 (set_attr "conds" "*,clob,clob,*,clob,clob,clob")
491 (set_attr "length" "*,8,8,*,8,8,8")
492 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits,*,*,*")]
495 (define_insn "*sub<mode>3_neon"
496 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
497 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
498 (match_operand:VDQ 2 "s_register_operand" "w")))]
499 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
500 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
501 [(set (attr "neon_type")
502 (if_then_else (match_test "<Is_float_mode>")
503 (if_then_else (match_test "<Is_d_reg>")
504 (const_string "neon_fp_vadd_ddd_vabs_dd")
505 (const_string "neon_fp_vadd_qqq_vabs_qq"))
506 (const_string "neon_int_2")))]
509 (define_insn "subdi3_neon"
510 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r,?w")
511 (minus:DI (match_operand:DI 1 "s_register_operand" "w,0,r,0,w")
512 (match_operand:DI 2 "s_register_operand" "w,r,0,0,w")))
513 (clobber (reg:CC CC_REGNUM))]
516 switch (which_alternative)
518 case 0: /* fall through */
519 case 4: return "vsub.i64\t%P0, %P1, %P2";
520 case 1: /* fall through */
521 case 2: /* fall through */
522 case 3: return "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2";
523 default: gcc_unreachable ();
526 [(set_attr "neon_type" "neon_int_2,*,*,*,neon_int_2")
527 (set_attr "conds" "*,clob,clob,clob,*")
528 (set_attr "length" "*,8,8,8,*")
529 (set_attr "arch" "neon_for_64bits,*,*,*,avoid_neon_for_64bits")]
532 (define_insn "*mul<mode>3_neon"
533 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
534 (mult:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
535 (match_operand:VDQ 2 "s_register_operand" "w")))]
536 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
537 "vmul.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
538 [(set (attr "neon_type")
539 (if_then_else (match_test "<Is_float_mode>")
540 (if_then_else (match_test "<Is_d_reg>")
541 (const_string "neon_fp_vadd_ddd_vabs_dd")
542 (const_string "neon_fp_vadd_qqq_vabs_qq"))
543 (if_then_else (match_test "<Is_d_reg>")
545 (match_test "<Scalar_mul_8_16>")
546 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
547 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
548 (if_then_else (match_test "<Scalar_mul_8_16>")
549 (const_string "neon_mul_qqq_8_16_32_ddd_32")
550 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
553 (define_insn "mul<mode>3add<mode>_neon"
554 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
555 (plus:VDQ (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
556 (match_operand:VDQ 3 "s_register_operand" "w"))
557 (match_operand:VDQ 1 "s_register_operand" "0")))]
558 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
559 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
560 [(set (attr "neon_type")
561 (if_then_else (match_test "<Is_float_mode>")
562 (if_then_else (match_test "<Is_d_reg>")
563 (const_string "neon_fp_vmla_ddd")
564 (const_string "neon_fp_vmla_qqq"))
565 (if_then_else (match_test "<Is_d_reg>")
567 (match_test "<Scalar_mul_8_16>")
568 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
569 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
570 (if_then_else (match_test "<Scalar_mul_8_16>")
571 (const_string "neon_mla_qqq_8_16")
572 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
575 (define_insn "mul<mode>3neg<mode>add<mode>_neon"
576 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
577 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "0")
578 (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
579 (match_operand:VDQ 3 "s_register_operand" "w"))))]
580 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
581 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
582 [(set (attr "neon_type")
583 (if_then_else (match_test "<Is_float_mode>")
584 (if_then_else (match_test "<Is_d_reg>")
585 (const_string "neon_fp_vmla_ddd")
586 (const_string "neon_fp_vmla_qqq"))
587 (if_then_else (match_test "<Is_d_reg>")
589 (match_test "<Scalar_mul_8_16>")
590 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
591 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
592 (if_then_else (match_test "<Scalar_mul_8_16>")
593 (const_string "neon_mla_qqq_8_16")
594 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
597 ;; Fused multiply-accumulate
598 ;; We define each insn twice here:
599 ;; 1: with flag_unsafe_math_optimizations for the widening multiply phase
600 ;; to be able to use when converting to FMA.
601 ;; 2: without flag_unsafe_math_optimizations for the intrinsics to use.
602 (define_insn "fma<VCVTF:mode>4"
603 [(set (match_operand:VCVTF 0 "register_operand" "=w")
604 (fma:VCVTF (match_operand:VCVTF 1 "register_operand" "w")
605 (match_operand:VCVTF 2 "register_operand" "w")
606 (match_operand:VCVTF 3 "register_operand" "0")))]
607 "TARGET_NEON && TARGET_FMA && flag_unsafe_math_optimizations"
608 "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
609 [(set (attr "neon_type")
610 (if_then_else (match_test "<Is_d_reg>")
611 (const_string "neon_fp_vmla_ddd")
612 (const_string "neon_fp_vmla_qqq")))]
615 (define_insn "fma<VCVTF:mode>4_intrinsic"
616 [(set (match_operand:VCVTF 0 "register_operand" "=w")
617 (fma:VCVTF (match_operand:VCVTF 1 "register_operand" "w")
618 (match_operand:VCVTF 2 "register_operand" "w")
619 (match_operand:VCVTF 3 "register_operand" "0")))]
620 "TARGET_NEON && TARGET_FMA"
621 "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
622 [(set (attr "neon_type")
623 (if_then_else (match_test "<Is_d_reg>")
624 (const_string "neon_fp_vmla_ddd")
625 (const_string "neon_fp_vmla_qqq")))]
628 (define_insn "*fmsub<VCVTF:mode>4"
629 [(set (match_operand:VCVTF 0 "register_operand" "=w")
630 (fma:VCVTF (neg:VCVTF (match_operand:VCVTF 1 "register_operand" "w"))
631 (match_operand:VCVTF 2 "register_operand" "w")
632 (match_operand:VCVTF 3 "register_operand" "0")))]
633 "TARGET_NEON && TARGET_FMA && flag_unsafe_math_optimizations"
634 "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
635 [(set (attr "neon_type")
636 (if_then_else (match_test "<Is_d_reg>")
637 (const_string "neon_fp_vmla_ddd")
638 (const_string "neon_fp_vmla_qqq")))]
641 (define_insn "fmsub<VCVTF:mode>4_intrinsic"
642 [(set (match_operand:VCVTF 0 "register_operand" "=w")
643 (fma:VCVTF (neg:VCVTF (match_operand:VCVTF 1 "register_operand" "w"))
644 (match_operand:VCVTF 2 "register_operand" "w")
645 (match_operand:VCVTF 3 "register_operand" "0")))]
646 "TARGET_NEON && TARGET_FMA"
647 "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
648 [(set (attr "neon_type")
649 (if_then_else (match_test "<Is_d_reg>")
650 (const_string "neon_fp_vmla_ddd")
651 (const_string "neon_fp_vmla_qqq")))]
654 (define_insn "neon_vrint<NEON_VRINT:nvrint_variant><VCVTF:mode>"
655 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
656 (unspec:VCVTF [(match_operand:VCVTF 1
657 "s_register_operand" "w")]
659 "TARGET_NEON && TARGET_FPU_ARMV8"
660 "vrint<nvrint_variant>%?.f32\\t%<V_reg>0, %<V_reg>1"
661 [(set (attr "neon_type")
662 (if_then_else (match_test "<Is_d_reg>")
663 (const_string "neon_fp_vadd_ddd_vabs_dd")
664 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
667 (define_insn "ior<mode>3"
668 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
669 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
670 (match_operand:VDQ 2 "neon_logic_op2" "w,Dl")))]
673 switch (which_alternative)
675 case 0: return "vorr\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
676 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
677 <MODE>mode, 0, VALID_NEON_QREG_MODE (<MODE>mode));
678 default: gcc_unreachable ();
681 [(set_attr "neon_type" "neon_int_1")]
684 ;; The concrete forms of the Neon immediate-logic instructions are vbic and
685 ;; vorr. We support the pseudo-instruction vand instead, because that
686 ;; corresponds to the canonical form the middle-end expects to use for
687 ;; immediate bitwise-ANDs.
689 (define_insn "and<mode>3"
690 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
691 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
692 (match_operand:VDQ 2 "neon_inv_logic_op2" "w,DL")))]
695 switch (which_alternative)
697 case 0: return "vand\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
698 case 1: return neon_output_logic_immediate ("vand", &operands[2],
699 <MODE>mode, 1, VALID_NEON_QREG_MODE (<MODE>mode));
700 default: gcc_unreachable ();
703 [(set_attr "neon_type" "neon_int_1")]
706 (define_insn "orn<mode>3_neon"
707 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
708 (ior:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
709 (match_operand:VDQ 1 "s_register_operand" "w")))]
711 "vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
712 [(set_attr "neon_type" "neon_int_1")]
715 ;; TODO: investigate whether we should disable
716 ;; this and bicdi3_neon for the A8 in line with the other
718 (define_insn_and_split "orndi3_neon"
719 [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r")
720 (ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,0,0,r"))
721 (match_operand:DI 1 "s_register_operand" "w,r,r,0")))]
729 (TARGET_NEON && !(IS_VFP_REGNUM (REGNO (operands[0]))))"
730 [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
731 (set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))]
736 operands[3] = gen_highpart (SImode, operands[0]);
737 operands[0] = gen_lowpart (SImode, operands[0]);
738 operands[4] = gen_highpart (SImode, operands[2]);
739 operands[2] = gen_lowpart (SImode, operands[2]);
740 operands[5] = gen_highpart (SImode, operands[1]);
741 operands[1] = gen_lowpart (SImode, operands[1]);
745 emit_insn (gen_one_cmpldi2 (operands[0], operands[2]));
746 emit_insn (gen_iordi3 (operands[0], operands[1], operands[0]));
750 [(set_attr "neon_type" "neon_int_1,*,*,*")
751 (set_attr "length" "*,16,8,8")
752 (set_attr "arch" "any,a,t2,t2")]
755 (define_insn "bic<mode>3_neon"
756 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
757 (and:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
758 (match_operand:VDQ 1 "s_register_operand" "w")))]
760 "vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
761 [(set_attr "neon_type" "neon_int_1")]
764 ;; Compare to *anddi_notdi_di.
765 (define_insn "bicdi3_neon"
766 [(set (match_operand:DI 0 "s_register_operand" "=w,?=&r,?&r")
767 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0"))
768 (match_operand:DI 1 "s_register_operand" "w,0,r")))]
774 [(set_attr "neon_type" "neon_int_1,*,*")
775 (set_attr "length" "*,8,8")]
778 (define_insn "xor<mode>3"
779 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
780 (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
781 (match_operand:VDQ 2 "s_register_operand" "w")))]
783 "veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
784 [(set_attr "neon_type" "neon_int_1")]
787 (define_insn "one_cmpl<mode>2"
788 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
789 (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
791 "vmvn\t%<V_reg>0, %<V_reg>1"
792 [(set_attr "neon_type" "neon_int_1")]
795 (define_insn "abs<mode>2"
796 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
797 (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
799 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
800 [(set (attr "neon_type")
801 (if_then_else (match_test "<Is_float_mode>")
802 (if_then_else (match_test "<Is_d_reg>")
803 (const_string "neon_fp_vadd_ddd_vabs_dd")
804 (const_string "neon_fp_vadd_qqq_vabs_qq"))
805 (const_string "neon_int_3")))]
808 (define_insn "neg<mode>2"
809 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
810 (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
812 "vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
813 [(set (attr "neon_type")
814 (if_then_else (match_test "<Is_float_mode>")
815 (if_then_else (match_test "<Is_d_reg>")
816 (const_string "neon_fp_vadd_ddd_vabs_dd")
817 (const_string "neon_fp_vadd_qqq_vabs_qq"))
818 (const_string "neon_int_3")))]
821 (define_insn "negdi2_neon"
822 [(set (match_operand:DI 0 "s_register_operand" "=&w, w,r,&r")
823 (neg:DI (match_operand:DI 1 "s_register_operand" " w, w,0, r")))
824 (clobber (match_scratch:DI 2 "= X,&w,X, X"))
825 (clobber (reg:CC CC_REGNUM))]
828 [(set_attr "length" "8")]
831 ; Split negdi2_neon for vfp registers
833 [(set (match_operand:DI 0 "s_register_operand" "")
834 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
835 (clobber (match_scratch:DI 2 ""))
836 (clobber (reg:CC CC_REGNUM))]
837 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
838 [(set (match_dup 2) (const_int 0))
839 (parallel [(set (match_dup 0) (minus:DI (match_dup 2) (match_dup 1)))
840 (clobber (reg:CC CC_REGNUM))])]
842 if (!REG_P (operands[2]))
843 operands[2] = operands[0];
847 ; Split negdi2_neon for core registers
849 [(set (match_operand:DI 0 "s_register_operand" "")
850 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
851 (clobber (match_scratch:DI 2 ""))
852 (clobber (reg:CC CC_REGNUM))]
853 "TARGET_32BIT && reload_completed
854 && arm_general_register_operand (operands[0], DImode)"
855 [(parallel [(set (match_dup 0) (neg:DI (match_dup 1)))
856 (clobber (reg:CC CC_REGNUM))])]
860 (define_insn "*umin<mode>3_neon"
861 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
862 (umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
863 (match_operand:VDQIW 2 "s_register_operand" "w")))]
865 "vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
866 [(set_attr "neon_type" "neon_int_5")]
869 (define_insn "*umax<mode>3_neon"
870 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
871 (umax:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
872 (match_operand:VDQIW 2 "s_register_operand" "w")))]
874 "vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
875 [(set_attr "neon_type" "neon_int_5")]
878 (define_insn "*smin<mode>3_neon"
879 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
880 (smin:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
881 (match_operand:VDQW 2 "s_register_operand" "w")))]
883 "vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
884 [(set (attr "neon_type")
885 (if_then_else (match_test "<Is_float_mode>")
886 (const_string "neon_fp_vadd_ddd_vabs_dd")
887 (const_string "neon_int_5")))]
890 (define_insn "*smax<mode>3_neon"
891 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
892 (smax:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
893 (match_operand:VDQW 2 "s_register_operand" "w")))]
895 "vmax.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
896 [(set (attr "neon_type")
897 (if_then_else (match_test "<Is_float_mode>")
898 (const_string "neon_fp_vadd_ddd_vabs_dd")
899 (const_string "neon_int_5")))]
902 ; TODO: V2DI shifts are current disabled because there are bugs in the
903 ; generic vectorizer code. It ends up creating a V2DI constructor with
906 (define_insn "vashl<mode>3"
907 [(set (match_operand:VDQIW 0 "s_register_operand" "=w,w")
908 (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w,w")
909 (match_operand:VDQIW 2 "imm_lshift_or_reg_neon" "w,Dn")))]
912 switch (which_alternative)
914 case 0: return "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
915 case 1: return neon_output_shift_immediate ("vshl", 'i', &operands[2],
917 VALID_NEON_QREG_MODE (<MODE>mode),
919 default: gcc_unreachable ();
922 [(set (attr "neon_type")
923 (if_then_else (match_test "<Is_d_reg>")
924 (const_string "neon_vshl_ddd")
925 (const_string "neon_shift_3")))]
928 (define_insn "vashr<mode>3_imm"
929 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
930 (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
931 (match_operand:VDQIW 2 "imm_for_neon_rshift_operand" "Dn")))]
934 return neon_output_shift_immediate ("vshr", 's', &operands[2],
935 <MODE>mode, VALID_NEON_QREG_MODE (<MODE>mode),
938 [(set (attr "neon_type")
939 (if_then_else (match_test "<Is_d_reg>")
940 (const_string "neon_vshl_ddd")
941 (const_string "neon_shift_3")))]
944 (define_insn "vlshr<mode>3_imm"
945 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
946 (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
947 (match_operand:VDQIW 2 "imm_for_neon_rshift_operand" "Dn")))]
950 return neon_output_shift_immediate ("vshr", 'u', &operands[2],
951 <MODE>mode, VALID_NEON_QREG_MODE (<MODE>mode),
954 [(set (attr "neon_type")
955 (if_then_else (match_test "<Is_d_reg>")
956 (const_string "neon_vshl_ddd")
957 (const_string "neon_shift_3")))]
960 ; Used for implementing logical shift-right, which is a left-shift by a negative
961 ; amount, with signed operands. This is essentially the same as ashl<mode>3
962 ; above, but using an unspec in case GCC tries anything tricky with negative
965 (define_insn "ashl<mode>3_signed"
966 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
967 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
968 (match_operand:VDQI 2 "s_register_operand" "w")]
969 UNSPEC_ASHIFT_SIGNED))]
971 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
972 [(set (attr "neon_type")
973 (if_then_else (match_test "<Is_d_reg>")
974 (const_string "neon_vshl_ddd")
975 (const_string "neon_shift_3")))]
978 ; Used for implementing logical shift-right, which is a left-shift by a negative
979 ; amount, with unsigned operands.
981 (define_insn "ashl<mode>3_unsigned"
982 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
983 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
984 (match_operand:VDQI 2 "s_register_operand" "w")]
985 UNSPEC_ASHIFT_UNSIGNED))]
987 "vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
988 [(set (attr "neon_type")
989 (if_then_else (match_test "<Is_d_reg>")
990 (const_string "neon_vshl_ddd")
991 (const_string "neon_shift_3")))]
994 (define_expand "vashr<mode>3"
995 [(set (match_operand:VDQIW 0 "s_register_operand" "")
996 (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
997 (match_operand:VDQIW 2 "imm_rshift_or_reg_neon" "")))]
1000 if (s_register_operand (operands[2], <MODE>mode))
1002 rtx neg = gen_reg_rtx (<MODE>mode);
1003 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1004 emit_insn (gen_ashl<mode>3_signed (operands[0], operands[1], neg));
1007 emit_insn (gen_vashr<mode>3_imm (operands[0], operands[1], operands[2]));
1011 (define_expand "vlshr<mode>3"
1012 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1013 (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1014 (match_operand:VDQIW 2 "imm_rshift_or_reg_neon" "")))]
1017 if (s_register_operand (operands[2], <MODE>mode))
1019 rtx neg = gen_reg_rtx (<MODE>mode);
1020 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1021 emit_insn (gen_ashl<mode>3_unsigned (operands[0], operands[1], neg));
1024 emit_insn (gen_vlshr<mode>3_imm (operands[0], operands[1], operands[2]));
1030 ;; This pattern loads a 32-bit shift count into a 64-bit NEON register,
1031 ;; leaving the upper half uninitalized. This is OK since the shift
1032 ;; instruction only looks at the low 8 bits anyway. To avoid confusing
1033 ;; data flow analysis however, we pretend the full register is set
1035 (define_insn "neon_load_count"
1036 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
1037 (unspec:DI [(match_operand:SI 1 "nonimmediate_operand" "Um,r")]
1038 UNSPEC_LOAD_COUNT))]
1041 vld1.32\t{%P0[0]}, %A1
1042 vmov.32\t%P0[0], %1"
1043 [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")]
1046 (define_insn "ashldi3_neon_noclobber"
1047 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
1048 (ashift:DI (match_operand:DI 1 "s_register_operand" " w,w")
1049 (match_operand:DI 2 "reg_or_int_operand" " i,w")))]
1050 "TARGET_NEON && reload_completed
1051 && (!CONST_INT_P (operands[2])
1052 || (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 64))"
1054 vshl.u64\t%P0, %P1, %2
1055 vshl.u64\t%P0, %P1, %P2"
1056 [(set_attr "neon_type" "neon_vshl_ddd,neon_vshl_ddd")]
1059 (define_insn_and_split "ashldi3_neon"
1060 [(set (match_operand:DI 0 "s_register_operand" "= w, w,?&r,?r, ?w,w")
1061 (ashift:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, r, 0w,w")
1062 (match_operand:SI 2 "general_operand" "rUm, i, r, i,rUm,i")))
1063 (clobber (match_scratch:SI 3 "= X, X,?&r, X, X,X"))
1064 (clobber (match_scratch:SI 4 "= X, X,?&r, X, X,X"))
1065 (clobber (match_scratch:DI 5 "=&w, X, X, X, &w,X"))
1066 (clobber (reg:CC_C CC_REGNUM))]
1069 "TARGET_NEON && reload_completed"
1073 if (IS_VFP_REGNUM (REGNO (operands[0])))
1075 if (CONST_INT_P (operands[2]))
1077 if (INTVAL (operands[2]) < 1)
1079 emit_insn (gen_movdi (operands[0], operands[1]));
1082 else if (INTVAL (operands[2]) > 63)
1083 operands[2] = gen_rtx_CONST_INT (VOIDmode, 63);
1087 emit_insn (gen_neon_load_count (operands[5], operands[2]));
1088 operands[2] = operands[5];
1091 /* Ditch the unnecessary clobbers. */
1092 emit_insn (gen_ashldi3_neon_noclobber (operands[0], operands[1],
1097 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
1098 /* This clobbers CC. */
1099 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
1101 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
1102 operands[2], operands[3], operands[4]);
1106 [(set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")
1107 (set_attr "opt" "*,*,speed,speed,*,*")]
1110 ; The shift amount needs to be negated for right-shifts
1111 (define_insn "signed_shift_di3_neon"
1112 [(set (match_operand:DI 0 "s_register_operand" "=w")
1113 (unspec:DI [(match_operand:DI 1 "s_register_operand" " w")
1114 (match_operand:DI 2 "s_register_operand" " w")]
1115 UNSPEC_ASHIFT_SIGNED))]
1116 "TARGET_NEON && reload_completed"
1117 "vshl.s64\t%P0, %P1, %P2"
1118 [(set_attr "neon_type" "neon_vshl_ddd")]
1121 ; The shift amount needs to be negated for right-shifts
1122 (define_insn "unsigned_shift_di3_neon"
1123 [(set (match_operand:DI 0 "s_register_operand" "=w")
1124 (unspec:DI [(match_operand:DI 1 "s_register_operand" " w")
1125 (match_operand:DI 2 "s_register_operand" " w")]
1126 UNSPEC_ASHIFT_UNSIGNED))]
1127 "TARGET_NEON && reload_completed"
1128 "vshl.u64\t%P0, %P1, %P2"
1129 [(set_attr "neon_type" "neon_vshl_ddd")]
1132 (define_insn "ashrdi3_neon_imm_noclobber"
1133 [(set (match_operand:DI 0 "s_register_operand" "=w")
1134 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" " w")
1135 (match_operand:DI 2 "const_int_operand" " i")))]
1136 "TARGET_NEON && reload_completed
1137 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64"
1138 "vshr.s64\t%P0, %P1, %2"
1139 [(set_attr "neon_type" "neon_vshl_ddd")]
1142 (define_insn "lshrdi3_neon_imm_noclobber"
1143 [(set (match_operand:DI 0 "s_register_operand" "=w")
1144 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" " w")
1145 (match_operand:DI 2 "const_int_operand" " i")))]
1146 "TARGET_NEON && reload_completed
1147 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64"
1148 "vshr.u64\t%P0, %P1, %2"
1149 [(set_attr "neon_type" "neon_vshl_ddd")]
1154 (define_insn_and_split "<shift>di3_neon"
1155 [(set (match_operand:DI 0 "s_register_operand" "= w, w,?&r,?r,?w,?w")
1156 (rshifts:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, r,0w, w")
1157 (match_operand:SI 2 "reg_or_int_operand" " r, i, r, i, r, i")))
1158 (clobber (match_scratch:SI 3 "=2r, X, &r, X,2r, X"))
1159 (clobber (match_scratch:SI 4 "= X, X, &r, X, X, X"))
1160 (clobber (match_scratch:DI 5 "=&w, X, X, X,&w, X"))
1161 (clobber (reg:CC CC_REGNUM))]
1164 "TARGET_NEON && reload_completed"
1168 if (IS_VFP_REGNUM (REGNO (operands[0])))
1170 if (CONST_INT_P (operands[2]))
1172 if (INTVAL (operands[2]) < 1)
1174 emit_insn (gen_movdi (operands[0], operands[1]));
1177 else if (INTVAL (operands[2]) > 64)
1178 operands[2] = gen_rtx_CONST_INT (VOIDmode, 64);
1180 /* Ditch the unnecessary clobbers. */
1181 emit_insn (gen_<shift>di3_neon_imm_noclobber (operands[0],
1187 /* We must use a negative left-shift. */
1188 emit_insn (gen_negsi2 (operands[3], operands[2]));
1189 emit_insn (gen_neon_load_count (operands[5], operands[3]));
1190 emit_insn (gen_<shifttype>_shift_di3_neon (operands[0], operands[1],
1196 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
1197 /* This clobbers CC. */
1198 emit_insn (gen_arm_<shift>di3_1bit (operands[0], operands[1]));
1200 /* This clobbers CC (ASHIFTRT by register only). */
1201 arm_emit_coreregs_64bit_shift (<CODE>, operands[0], operands[1],
1202 operands[2], operands[3], operands[4]);
1207 [(set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")
1208 (set_attr "opt" "*,*,speed,speed,*,*")]
1211 ;; Widening operations
1213 (define_insn "widen_ssum<mode>3"
1214 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1215 (plus:<V_widen> (sign_extend:<V_widen>
1216 (match_operand:VW 1 "s_register_operand" "%w"))
1217 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1219 "vaddw.<V_s_elem>\t%q0, %q2, %P1"
1220 [(set_attr "neon_type" "neon_int_3")]
1223 (define_insn "widen_usum<mode>3"
1224 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1225 (plus:<V_widen> (zero_extend:<V_widen>
1226 (match_operand:VW 1 "s_register_operand" "%w"))
1227 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1229 "vaddw.<V_u_elem>\t%q0, %q2, %P1"
1230 [(set_attr "neon_type" "neon_int_3")]
1233 ;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
1234 ;; shift-count granularity. That's good enough for the middle-end's current
1237 ;; Note that it's not safe to perform such an operation in big-endian mode,
1238 ;; due to element-ordering issues.
1240 (define_expand "vec_shr_<mode>"
1241 [(match_operand:VDQ 0 "s_register_operand" "")
1242 (match_operand:VDQ 1 "s_register_operand" "")
1243 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1244 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1247 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1248 const int width = GET_MODE_BITSIZE (<MODE>mode);
1249 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1250 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1251 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1253 if (num_bits == width)
1255 emit_move_insn (operands[0], operands[1]);
1259 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1260 operands[0] = gen_lowpart (bvecmode, operands[0]);
1261 operands[1] = gen_lowpart (bvecmode, operands[1]);
1263 emit_insn (gen_ext (operands[0], operands[1], zero_reg,
1264 GEN_INT (num_bits / BITS_PER_UNIT)));
1268 (define_expand "vec_shl_<mode>"
1269 [(match_operand:VDQ 0 "s_register_operand" "")
1270 (match_operand:VDQ 1 "s_register_operand" "")
1271 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1272 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1275 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1276 const int width = GET_MODE_BITSIZE (<MODE>mode);
1277 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1278 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1279 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1283 emit_move_insn (operands[0], CONST0_RTX (<MODE>mode));
1287 num_bits = width - num_bits;
1289 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1290 operands[0] = gen_lowpart (bvecmode, operands[0]);
1291 operands[1] = gen_lowpart (bvecmode, operands[1]);
1293 emit_insn (gen_ext (operands[0], zero_reg, operands[1],
1294 GEN_INT (num_bits / BITS_PER_UNIT)));
1298 ;; Helpers for quad-word reduction operations
1300 ; Add (or smin, smax...) the low N/2 elements of the N-element vector
1301 ; operand[1] to the high N/2 elements of same. Put the result in operand[0], an
1302 ; N/2-element vector.
1304 (define_insn "quad_halves_<code>v4si"
1305 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
1307 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
1308 (parallel [(const_int 0) (const_int 1)]))
1309 (vec_select:V2SI (match_dup 1)
1310 (parallel [(const_int 2) (const_int 3)]))))]
1312 "<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1"
1313 [(set_attr "vqh_mnem" "<VQH_mnem>")
1314 (set (attr "neon_type")
1315 (if_then_else (eq_attr "vqh_mnem" "vadd")
1316 (const_string "neon_int_1") (const_string "neon_int_5")))]
1319 (define_insn "quad_halves_<code>v4sf"
1320 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
1322 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
1323 (parallel [(const_int 0) (const_int 1)]))
1324 (vec_select:V2SF (match_dup 1)
1325 (parallel [(const_int 2) (const_int 3)]))))]
1326 "TARGET_NEON && flag_unsafe_math_optimizations"
1327 "<VQH_mnem>.f32\t%P0, %e1, %f1"
1328 [(set_attr "vqh_mnem" "<VQH_mnem>")
1329 (set (attr "neon_type")
1330 (if_then_else (eq_attr "vqh_mnem" "vadd")
1331 (const_string "neon_int_1") (const_string "neon_int_5")))]
1334 (define_insn "quad_halves_<code>v8hi"
1335 [(set (match_operand:V4HI 0 "s_register_operand" "+w")
1337 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
1338 (parallel [(const_int 0) (const_int 1)
1339 (const_int 2) (const_int 3)]))
1340 (vec_select:V4HI (match_dup 1)
1341 (parallel [(const_int 4) (const_int 5)
1342 (const_int 6) (const_int 7)]))))]
1344 "<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1"
1345 [(set_attr "vqh_mnem" "<VQH_mnem>")
1346 (set (attr "neon_type")
1347 (if_then_else (eq_attr "vqh_mnem" "vadd")
1348 (const_string "neon_int_1") (const_string "neon_int_5")))]
1351 (define_insn "quad_halves_<code>v16qi"
1352 [(set (match_operand:V8QI 0 "s_register_operand" "+w")
1354 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
1355 (parallel [(const_int 0) (const_int 1)
1356 (const_int 2) (const_int 3)
1357 (const_int 4) (const_int 5)
1358 (const_int 6) (const_int 7)]))
1359 (vec_select:V8QI (match_dup 1)
1360 (parallel [(const_int 8) (const_int 9)
1361 (const_int 10) (const_int 11)
1362 (const_int 12) (const_int 13)
1363 (const_int 14) (const_int 15)]))))]
1365 "<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1"
1366 [(set_attr "vqh_mnem" "<VQH_mnem>")
1367 (set (attr "neon_type")
1368 (if_then_else (eq_attr "vqh_mnem" "vadd")
1369 (const_string "neon_int_1") (const_string "neon_int_5")))]
1372 (define_expand "move_hi_quad_<mode>"
1373 [(match_operand:ANY128 0 "s_register_operand" "")
1374 (match_operand:<V_HALF> 1 "s_register_operand" "")]
1377 emit_move_insn (simplify_gen_subreg (<V_HALF>mode, operands[0], <MODE>mode,
1378 GET_MODE_SIZE (<V_HALF>mode)),
1383 (define_expand "move_lo_quad_<mode>"
1384 [(match_operand:ANY128 0 "s_register_operand" "")
1385 (match_operand:<V_HALF> 1 "s_register_operand" "")]
1388 emit_move_insn (simplify_gen_subreg (<V_HALF>mode, operands[0],
1394 ;; Reduction operations
1396 (define_expand "reduc_splus_<mode>"
1397 [(match_operand:VD 0 "s_register_operand" "")
1398 (match_operand:VD 1 "s_register_operand" "")]
1399 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1401 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1402 &gen_neon_vpadd_internal<mode>);
1406 (define_expand "reduc_splus_<mode>"
1407 [(match_operand:VQ 0 "s_register_operand" "")
1408 (match_operand:VQ 1 "s_register_operand" "")]
1409 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)
1410 && !BYTES_BIG_ENDIAN"
1412 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1413 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1415 emit_insn (gen_quad_halves_plus<mode> (step1, operands[1]));
1416 emit_insn (gen_reduc_splus_<V_half> (res_d, step1));
1417 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1422 (define_insn "reduc_splus_v2di"
1423 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1424 (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")]
1426 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1427 "vadd.i64\t%e0, %e1, %f1"
1428 [(set_attr "neon_type" "neon_int_1")]
1431 ;; NEON does not distinguish between signed and unsigned addition except on
1432 ;; widening operations.
1433 (define_expand "reduc_uplus_<mode>"
1434 [(match_operand:VDQI 0 "s_register_operand" "")
1435 (match_operand:VDQI 1 "s_register_operand" "")]
1436 "TARGET_NEON && (<Is_d_reg> || !BYTES_BIG_ENDIAN)"
1438 emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1]));
1442 (define_expand "reduc_smin_<mode>"
1443 [(match_operand:VD 0 "s_register_operand" "")
1444 (match_operand:VD 1 "s_register_operand" "")]
1445 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1447 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1448 &gen_neon_vpsmin<mode>);
1452 (define_expand "reduc_smin_<mode>"
1453 [(match_operand:VQ 0 "s_register_operand" "")
1454 (match_operand:VQ 1 "s_register_operand" "")]
1455 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)
1456 && !BYTES_BIG_ENDIAN"
1458 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1459 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1461 emit_insn (gen_quad_halves_smin<mode> (step1, operands[1]));
1462 emit_insn (gen_reduc_smin_<V_half> (res_d, step1));
1463 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1468 (define_expand "reduc_smax_<mode>"
1469 [(match_operand:VD 0 "s_register_operand" "")
1470 (match_operand:VD 1 "s_register_operand" "")]
1471 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1473 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1474 &gen_neon_vpsmax<mode>);
1478 (define_expand "reduc_smax_<mode>"
1479 [(match_operand:VQ 0 "s_register_operand" "")
1480 (match_operand:VQ 1 "s_register_operand" "")]
1481 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)
1482 && !BYTES_BIG_ENDIAN"
1484 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1485 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1487 emit_insn (gen_quad_halves_smax<mode> (step1, operands[1]));
1488 emit_insn (gen_reduc_smax_<V_half> (res_d, step1));
1489 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1494 (define_expand "reduc_umin_<mode>"
1495 [(match_operand:VDI 0 "s_register_operand" "")
1496 (match_operand:VDI 1 "s_register_operand" "")]
1499 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1500 &gen_neon_vpumin<mode>);
1504 (define_expand "reduc_umin_<mode>"
1505 [(match_operand:VQI 0 "s_register_operand" "")
1506 (match_operand:VQI 1 "s_register_operand" "")]
1507 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1509 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1510 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1512 emit_insn (gen_quad_halves_umin<mode> (step1, operands[1]));
1513 emit_insn (gen_reduc_umin_<V_half> (res_d, step1));
1514 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1519 (define_expand "reduc_umax_<mode>"
1520 [(match_operand:VDI 0 "s_register_operand" "")
1521 (match_operand:VDI 1 "s_register_operand" "")]
1524 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1525 &gen_neon_vpumax<mode>);
1529 (define_expand "reduc_umax_<mode>"
1530 [(match_operand:VQI 0 "s_register_operand" "")
1531 (match_operand:VQI 1 "s_register_operand" "")]
1532 "TARGET_NEON && !BYTES_BIG_ENDIAN"
1534 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1535 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1537 emit_insn (gen_quad_halves_umax<mode> (step1, operands[1]));
1538 emit_insn (gen_reduc_umax_<V_half> (res_d, step1));
1539 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1544 (define_insn "neon_vpadd_internal<mode>"
1545 [(set (match_operand:VD 0 "s_register_operand" "=w")
1546 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1547 (match_operand:VD 2 "s_register_operand" "w")]
1550 "vpadd.<V_if_elem>\t%P0, %P1, %P2"
1551 ;; Assume this schedules like vadd.
1552 [(set (attr "neon_type")
1553 (if_then_else (match_test "<Is_float_mode>")
1554 (if_then_else (match_test "<Is_d_reg>")
1555 (const_string "neon_fp_vadd_ddd_vabs_dd")
1556 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1557 (const_string "neon_int_1")))]
1560 (define_insn "neon_vpsmin<mode>"
1561 [(set (match_operand:VD 0 "s_register_operand" "=w")
1562 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1563 (match_operand:VD 2 "s_register_operand" "w")]
1566 "vpmin.<V_s_elem>\t%P0, %P1, %P2"
1567 ;; Assume this schedules like vmin.
1568 [(set (attr "neon_type")
1569 (if_then_else (match_test "<Is_float_mode>")
1570 (const_string "neon_fp_vadd_ddd_vabs_dd")
1571 (const_string "neon_int_5")))]
1574 (define_insn "neon_vpsmax<mode>"
1575 [(set (match_operand:VD 0 "s_register_operand" "=w")
1576 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1577 (match_operand:VD 2 "s_register_operand" "w")]
1580 "vpmax.<V_s_elem>\t%P0, %P1, %P2"
1581 ;; Assume this schedules like vmax.
1582 [(set (attr "neon_type")
1583 (if_then_else (match_test "<Is_float_mode>")
1584 (const_string "neon_fp_vadd_ddd_vabs_dd")
1585 (const_string "neon_int_5")))]
1588 (define_insn "neon_vpumin<mode>"
1589 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1590 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1591 (match_operand:VDI 2 "s_register_operand" "w")]
1594 "vpmin.<V_u_elem>\t%P0, %P1, %P2"
1595 ;; Assume this schedules like umin.
1596 [(set_attr "neon_type" "neon_int_5")]
1599 (define_insn "neon_vpumax<mode>"
1600 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1601 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1602 (match_operand:VDI 2 "s_register_operand" "w")]
1605 "vpmax.<V_u_elem>\t%P0, %P1, %P2"
1606 ;; Assume this schedules like umax.
1607 [(set_attr "neon_type" "neon_int_5")]
1610 ;; Saturating arithmetic
1612 ; NOTE: Neon supports many more saturating variants of instructions than the
1613 ; following, but these are all GCC currently understands.
1614 ; FIXME: Actually, GCC doesn't know how to create saturating add/sub by itself
1615 ; yet either, although these patterns may be used by intrinsics when they're
1618 (define_insn "*ss_add<mode>_neon"
1619 [(set (match_operand:VD 0 "s_register_operand" "=w")
1620 (ss_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1621 (match_operand:VD 2 "s_register_operand" "w")))]
1623 "vqadd.<V_s_elem>\t%P0, %P1, %P2"
1624 [(set_attr "neon_type" "neon_int_4")]
1627 (define_insn "*us_add<mode>_neon"
1628 [(set (match_operand:VD 0 "s_register_operand" "=w")
1629 (us_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1630 (match_operand:VD 2 "s_register_operand" "w")))]
1632 "vqadd.<V_u_elem>\t%P0, %P1, %P2"
1633 [(set_attr "neon_type" "neon_int_4")]
1636 (define_insn "*ss_sub<mode>_neon"
1637 [(set (match_operand:VD 0 "s_register_operand" "=w")
1638 (ss_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1639 (match_operand:VD 2 "s_register_operand" "w")))]
1641 "vqsub.<V_s_elem>\t%P0, %P1, %P2"
1642 [(set_attr "neon_type" "neon_int_5")]
1645 (define_insn "*us_sub<mode>_neon"
1646 [(set (match_operand:VD 0 "s_register_operand" "=w")
1647 (us_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1648 (match_operand:VD 2 "s_register_operand" "w")))]
1650 "vqsub.<V_u_elem>\t%P0, %P1, %P2"
1651 [(set_attr "neon_type" "neon_int_5")]
1654 ;; Conditional instructions. These are comparisons with conditional moves for
1655 ;; vectors. They perform the assignment:
1657 ;; Vop0 = (Vop4 <op3> Vop5) ? Vop1 : Vop2;
1659 ;; where op3 is <, <=, ==, !=, >= or >. Operations are performed
1662 (define_expand "vcond<mode><mode>"
1663 [(set (match_operand:VDQW 0 "s_register_operand" "")
1665 (match_operator 3 "comparison_operator"
1666 [(match_operand:VDQW 4 "s_register_operand" "")
1667 (match_operand:VDQW 5 "nonmemory_operand" "")])
1668 (match_operand:VDQW 1 "s_register_operand" "")
1669 (match_operand:VDQW 2 "s_register_operand" "")))]
1670 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1672 HOST_WIDE_INT magic_word = (<MODE>mode == V2SFmode || <MODE>mode == V4SFmode)
1674 rtx magic_rtx = GEN_INT (magic_word);
1676 int swap_bsl_operands = 0;
1677 rtx mask = gen_reg_rtx (<V_cmp_result>mode);
1678 rtx tmp = gen_reg_rtx (<V_cmp_result>mode);
1680 rtx (*base_comparison) (rtx, rtx, rtx, rtx);
1681 rtx (*complimentary_comparison) (rtx, rtx, rtx, rtx);
1683 switch (GET_CODE (operands[3]))
1688 if (!REG_P (operands[5])
1689 && (operands[5] != CONST0_RTX (<MODE>mode)))
1690 operands[5] = force_reg (<MODE>mode, operands[5]);
1693 if (!REG_P (operands[5]))
1694 operands[5] = force_reg (<MODE>mode, operands[5]);
1697 switch (GET_CODE (operands[3]))
1707 base_comparison = gen_neon_vcge<mode>;
1708 complimentary_comparison = gen_neon_vcgt<mode>;
1716 base_comparison = gen_neon_vcgt<mode>;
1717 complimentary_comparison = gen_neon_vcge<mode>;
1722 base_comparison = gen_neon_vceq<mode>;
1723 complimentary_comparison = gen_neon_vceq<mode>;
1729 switch (GET_CODE (operands[3]))
1736 /* The easy case. Here we emit one of vcge, vcgt or vceq.
1737 As a LT b <=> b GE a && a LE b <=> b GT a. Our transformations are:
1745 emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx));
1747 emit_insn (complimentary_comparison (mask, operands[5], operands[4], magic_rtx));
1754 /* Vector compare returns false for lanes which are unordered, so if we use
1755 the inverse of the comparison we actually want to emit, then
1756 swap the operands to BSL, we will end up with the correct result.
1757 Note that a NE NaN and NaN NE b are true for all a, b.
1759 Our transformations are:
1764 a NE b -> !(a EQ b) */
1767 emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx));
1769 emit_insn (complimentary_comparison (mask, operands[5], operands[4], magic_rtx));
1771 swap_bsl_operands = 1;
1774 /* We check (a > b || b > a). combining these comparisons give us
1775 true iff !(a != b && a ORDERED b), swapping the operands to BSL
1776 will then give us (a == b || a UNORDERED b) as intended. */
1778 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5], magic_rtx));
1779 emit_insn (gen_neon_vcgt<mode> (tmp, operands[5], operands[4], magic_rtx));
1780 emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
1781 swap_bsl_operands = 1;
1784 /* Operands are ORDERED iff (a > b || b >= a).
1785 Swapping the operands to BSL will give the UNORDERED case. */
1786 swap_bsl_operands = 1;
1789 emit_insn (gen_neon_vcgt<mode> (tmp, operands[4], operands[5], magic_rtx));
1790 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4], magic_rtx));
1791 emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
1797 if (swap_bsl_operands)
1798 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1801 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1806 (define_expand "vcondu<mode><mode>"
1807 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1809 (match_operator 3 "arm_comparison_operator"
1810 [(match_operand:VDQIW 4 "s_register_operand" "")
1811 (match_operand:VDQIW 5 "s_register_operand" "")])
1812 (match_operand:VDQIW 1 "s_register_operand" "")
1813 (match_operand:VDQIW 2 "s_register_operand" "")))]
1817 int inverse = 0, immediate_zero = 0;
1819 mask = gen_reg_rtx (<V_cmp_result>mode);
1821 if (operands[5] == CONST0_RTX (<MODE>mode))
1823 else if (!REG_P (operands[5]))
1824 operands[5] = force_reg (<MODE>mode, operands[5]);
1826 switch (GET_CODE (operands[3]))
1829 emit_insn (gen_neon_vcge<mode> (mask, operands[4], operands[5],
1834 emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5],
1839 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1845 emit_insn (gen_neon_vcle<mode> (mask, operands[4], operands[5],
1848 emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4],
1854 emit_insn (gen_neon_vclt<mode> (mask, operands[4], operands[5],
1857 emit_insn (gen_neon_vcgt<mode> (mask, operands[5], operands[4],
1862 emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1872 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1875 emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1881 ;; Patterns for builtins.
1883 ; good for plain vadd, vaddq.
1885 (define_expand "neon_vadd<mode>"
1886 [(match_operand:VDQX 0 "s_register_operand" "=w")
1887 (match_operand:VDQX 1 "s_register_operand" "w")
1888 (match_operand:VDQX 2 "s_register_operand" "w")
1889 (match_operand:SI 3 "immediate_operand" "i")]
1892 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1893 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[2]));
1895 emit_insn (gen_neon_vadd<mode>_unspec (operands[0], operands[1],
1900 ; Note that NEON operations don't support the full IEEE 754 standard: in
1901 ; particular, denormal values are flushed to zero. This means that GCC cannot
1902 ; use those instructions for autovectorization, etc. unless
1903 ; -funsafe-math-optimizations is in effect (in which case flush-to-zero
1904 ; behaviour is permissible). Intrinsic operations (provided by the arm_neon.h
1905 ; header) must work in either case: if -funsafe-math-optimizations is given,
1906 ; intrinsics expand to "canonical" RTL where possible, otherwise intrinsics
1907 ; expand to unspecs (which may potentially limit the extent to which they might
1908 ; be optimized by generic code).
1910 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1912 (define_insn "neon_vadd<mode>_unspec"
1913 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1914 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1915 (match_operand:VDQX 2 "s_register_operand" "w")]
1918 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1919 [(set (attr "neon_type")
1920 (if_then_else (match_test "<Is_float_mode>")
1921 (if_then_else (match_test "<Is_d_reg>")
1922 (const_string "neon_fp_vadd_ddd_vabs_dd")
1923 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1924 (const_string "neon_int_1")))]
1927 ; operand 3 represents in bits:
1928 ; bit 0: signed (vs unsigned).
1929 ; bit 1: rounding (vs none).
1931 (define_insn "neon_vaddl<mode>"
1932 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1933 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1934 (match_operand:VDI 2 "s_register_operand" "w")
1935 (match_operand:SI 3 "immediate_operand" "i")]
1938 "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1939 [(set_attr "neon_type" "neon_int_3")]
1942 (define_insn "neon_vaddw<mode>"
1943 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1944 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1945 (match_operand:VDI 2 "s_register_operand" "w")
1946 (match_operand:SI 3 "immediate_operand" "i")]
1949 "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
1950 [(set_attr "neon_type" "neon_int_2")]
1955 (define_insn "neon_vhadd<mode>"
1956 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1957 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1958 (match_operand:VDQIW 2 "s_register_operand" "w")
1959 (match_operand:SI 3 "immediate_operand" "i")]
1962 "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1963 [(set_attr "neon_type" "neon_int_4")]
1966 (define_insn "neon_vqadd<mode>"
1967 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1968 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1969 (match_operand:VDQIX 2 "s_register_operand" "w")
1970 (match_operand:SI 3 "immediate_operand" "i")]
1973 "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1974 [(set_attr "neon_type" "neon_int_4")]
1977 (define_insn "neon_vaddhn<mode>"
1978 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
1979 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
1980 (match_operand:VN 2 "s_register_operand" "w")
1981 (match_operand:SI 3 "immediate_operand" "i")]
1984 "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2"
1985 [(set_attr "neon_type" "neon_int_4")]
1988 ;; We cannot replace this unspec with mul<mode>3 because of the odd
1989 ;; polynomial multiplication case that can specified by operand 3.
1990 (define_insn "neon_vmul<mode>"
1991 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1992 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1993 (match_operand:VDQW 2 "s_register_operand" "w")
1994 (match_operand:SI 3 "immediate_operand" "i")]
1997 "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1998 [(set (attr "neon_type")
1999 (if_then_else (match_test "<Is_float_mode>")
2000 (if_then_else (match_test "<Is_d_reg>")
2001 (const_string "neon_fp_vadd_ddd_vabs_dd")
2002 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2003 (if_then_else (match_test "<Is_d_reg>")
2005 (match_test "<Scalar_mul_8_16>")
2006 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2007 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
2008 (if_then_else (match_test "<Scalar_mul_8_16>")
2009 (const_string "neon_mul_qqq_8_16_32_ddd_32")
2010 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
2013 (define_expand "neon_vmla<mode>"
2014 [(match_operand:VDQW 0 "s_register_operand" "=w")
2015 (match_operand:VDQW 1 "s_register_operand" "0")
2016 (match_operand:VDQW 2 "s_register_operand" "w")
2017 (match_operand:VDQW 3 "s_register_operand" "w")
2018 (match_operand:SI 4 "immediate_operand" "i")]
2021 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2022 emit_insn (gen_mul<mode>3add<mode>_neon (operands[0], operands[1],
2023 operands[2], operands[3]));
2025 emit_insn (gen_neon_vmla<mode>_unspec (operands[0], operands[1],
2026 operands[2], operands[3]));
2030 (define_expand "neon_vfma<VCVTF:mode>"
2031 [(match_operand:VCVTF 0 "s_register_operand")
2032 (match_operand:VCVTF 1 "s_register_operand")
2033 (match_operand:VCVTF 2 "s_register_operand")
2034 (match_operand:VCVTF 3 "s_register_operand")
2035 (match_operand:SI 4 "immediate_operand")]
2036 "TARGET_NEON && TARGET_FMA"
2038 emit_insn (gen_fma<mode>4_intrinsic (operands[0], operands[2], operands[3],
2043 (define_expand "neon_vfms<VCVTF:mode>"
2044 [(match_operand:VCVTF 0 "s_register_operand")
2045 (match_operand:VCVTF 1 "s_register_operand")
2046 (match_operand:VCVTF 2 "s_register_operand")
2047 (match_operand:VCVTF 3 "s_register_operand")
2048 (match_operand:SI 4 "immediate_operand")]
2049 "TARGET_NEON && TARGET_FMA"
2051 emit_insn (gen_fmsub<mode>4_intrinsic (operands[0], operands[2], operands[3],
2056 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2058 (define_insn "neon_vmla<mode>_unspec"
2059 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
2060 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
2061 (match_operand:VDQ 2 "s_register_operand" "w")
2062 (match_operand:VDQ 3 "s_register_operand" "w")]
2065 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2066 [(set (attr "neon_type")
2067 (if_then_else (match_test "<Is_float_mode>")
2068 (if_then_else (match_test "<Is_d_reg>")
2069 (const_string "neon_fp_vmla_ddd")
2070 (const_string "neon_fp_vmla_qqq"))
2071 (if_then_else (match_test "<Is_d_reg>")
2073 (match_test "<Scalar_mul_8_16>")
2074 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2075 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
2076 (if_then_else (match_test "<Scalar_mul_8_16>")
2077 (const_string "neon_mla_qqq_8_16")
2078 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
2081 (define_insn "neon_vmlal<mode>"
2082 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2083 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2084 (match_operand:VW 2 "s_register_operand" "w")
2085 (match_operand:VW 3 "s_register_operand" "w")
2086 (match_operand:SI 4 "immediate_operand" "i")]
2089 "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2090 [(set (attr "neon_type")
2091 (if_then_else (match_test "<Scalar_mul_8_16>")
2092 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2093 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2096 (define_expand "neon_vmls<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>3neg<mode>add<mode>_neon (operands[0],
2106 operands[1], operands[2], operands[3]));
2108 emit_insn (gen_neon_vmls<mode>_unspec (operands[0], operands[1],
2109 operands[2], operands[3]));
2113 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2115 (define_insn "neon_vmls<mode>_unspec"
2116 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
2117 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
2118 (match_operand:VDQ 2 "s_register_operand" "w")
2119 (match_operand:VDQ 3 "s_register_operand" "w")]
2122 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2123 [(set (attr "neon_type")
2124 (if_then_else (match_test "<Is_float_mode>")
2125 (if_then_else (match_test "<Is_d_reg>")
2126 (const_string "neon_fp_vmla_ddd")
2127 (const_string "neon_fp_vmla_qqq"))
2128 (if_then_else (match_test "<Is_d_reg>")
2130 (match_test "<Scalar_mul_8_16>")
2131 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2132 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
2134 (match_test "<Scalar_mul_8_16>")
2135 (const_string "neon_mla_qqq_8_16")
2136 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
2139 (define_insn "neon_vmlsl<mode>"
2140 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2141 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2142 (match_operand:VW 2 "s_register_operand" "w")
2143 (match_operand:VW 3 "s_register_operand" "w")
2144 (match_operand:SI 4 "immediate_operand" "i")]
2147 "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2148 [(set (attr "neon_type")
2149 (if_then_else (match_test "<Scalar_mul_8_16>")
2150 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2151 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2154 (define_insn "neon_vqdmulh<mode>"
2155 [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
2156 (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
2157 (match_operand:VMDQI 2 "s_register_operand" "w")
2158 (match_operand:SI 3 "immediate_operand" "i")]
2161 "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2162 [(set (attr "neon_type")
2163 (if_then_else (match_test "<Is_d_reg>")
2164 (if_then_else (match_test "<Scalar_mul_8_16>")
2165 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2166 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
2167 (if_then_else (match_test "<Scalar_mul_8_16>")
2168 (const_string "neon_mul_qqq_8_16_32_ddd_32")
2169 (const_string "neon_mul_qqq_8_16_32_ddd_32"))))]
2172 (define_insn "neon_vqdmlal<mode>"
2173 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2174 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2175 (match_operand:VMDI 2 "s_register_operand" "w")
2176 (match_operand:VMDI 3 "s_register_operand" "w")
2177 (match_operand:SI 4 "immediate_operand" "i")]
2180 "vqdmlal.<V_s_elem>\t%q0, %P2, %P3"
2181 [(set (attr "neon_type")
2182 (if_then_else (match_test "<Scalar_mul_8_16>")
2183 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2184 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2187 (define_insn "neon_vqdmlsl<mode>"
2188 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2189 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2190 (match_operand:VMDI 2 "s_register_operand" "w")
2191 (match_operand:VMDI 3 "s_register_operand" "w")
2192 (match_operand:SI 4 "immediate_operand" "i")]
2195 "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3"
2196 [(set (attr "neon_type")
2197 (if_then_else (match_test "<Scalar_mul_8_16>")
2198 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2199 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2202 (define_insn "neon_vmull<mode>"
2203 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2204 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2205 (match_operand:VW 2 "s_register_operand" "w")
2206 (match_operand:SI 3 "immediate_operand" "i")]
2209 "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2210 [(set (attr "neon_type")
2211 (if_then_else (match_test "<Scalar_mul_8_16>")
2212 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2213 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2216 (define_insn "neon_vqdmull<mode>"
2217 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2218 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
2219 (match_operand:VMDI 2 "s_register_operand" "w")
2220 (match_operand:SI 3 "immediate_operand" "i")]
2223 "vqdmull.<V_s_elem>\t%q0, %P1, %P2"
2224 [(set (attr "neon_type")
2225 (if_then_else (match_test "<Scalar_mul_8_16>")
2226 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2227 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2230 (define_expand "neon_vsub<mode>"
2231 [(match_operand:VDQX 0 "s_register_operand" "=w")
2232 (match_operand:VDQX 1 "s_register_operand" "w")
2233 (match_operand:VDQX 2 "s_register_operand" "w")
2234 (match_operand:SI 3 "immediate_operand" "i")]
2237 if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2238 emit_insn (gen_sub<mode>3 (operands[0], operands[1], operands[2]));
2240 emit_insn (gen_neon_vsub<mode>_unspec (operands[0], operands[1],
2245 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2247 (define_insn "neon_vsub<mode>_unspec"
2248 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
2249 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
2250 (match_operand:VDQX 2 "s_register_operand" "w")]
2253 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2254 [(set (attr "neon_type")
2255 (if_then_else (match_test "<Is_float_mode>")
2256 (if_then_else (match_test "<Is_d_reg>")
2257 (const_string "neon_fp_vadd_ddd_vabs_dd")
2258 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2259 (const_string "neon_int_2")))]
2262 (define_insn "neon_vsubl<mode>"
2263 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2264 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
2265 (match_operand:VDI 2 "s_register_operand" "w")
2266 (match_operand:SI 3 "immediate_operand" "i")]
2269 "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2270 [(set_attr "neon_type" "neon_int_2")]
2273 (define_insn "neon_vsubw<mode>"
2274 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2275 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
2276 (match_operand:VDI 2 "s_register_operand" "w")
2277 (match_operand:SI 3 "immediate_operand" "i")]
2280 "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
2281 [(set_attr "neon_type" "neon_int_2")]
2284 (define_insn "neon_vqsub<mode>"
2285 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2286 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2287 (match_operand:VDQIX 2 "s_register_operand" "w")
2288 (match_operand:SI 3 "immediate_operand" "i")]
2291 "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2292 [(set_attr "neon_type" "neon_int_5")]
2295 (define_insn "neon_vhsub<mode>"
2296 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2297 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2298 (match_operand:VDQIW 2 "s_register_operand" "w")
2299 (match_operand:SI 3 "immediate_operand" "i")]
2302 "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2303 [(set_attr "neon_type" "neon_int_5")]
2306 (define_insn "neon_vsubhn<mode>"
2307 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2308 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2309 (match_operand:VN 2 "s_register_operand" "w")
2310 (match_operand:SI 3 "immediate_operand" "i")]
2313 "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2"
2314 [(set_attr "neon_type" "neon_int_4")]
2317 (define_insn "neon_vceq<mode>"
2318 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2319 (unspec:<V_cmp_result>
2320 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2321 (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2322 (match_operand:SI 3 "immediate_operand" "i,i")]
2326 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2327 vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, #0"
2328 [(set (attr "neon_type")
2329 (if_then_else (match_test "<Is_float_mode>")
2330 (if_then_else (match_test "<Is_d_reg>")
2331 (const_string "neon_fp_vadd_ddd_vabs_dd")
2332 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2333 (const_string "neon_int_5")))]
2336 (define_insn "neon_vcge<mode>"
2337 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2338 (unspec:<V_cmp_result>
2339 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2340 (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2341 (match_operand:SI 3 "immediate_operand" "i,i")]
2345 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2346 vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2347 [(set (attr "neon_type")
2348 (if_then_else (match_test "<Is_float_mode>")
2349 (if_then_else (match_test "<Is_d_reg>")
2350 (const_string "neon_fp_vadd_ddd_vabs_dd")
2351 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2352 (const_string "neon_int_5")))]
2355 (define_insn "neon_vcgeu<mode>"
2356 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2357 (unspec:<V_cmp_result>
2358 [(match_operand:VDQIW 1 "s_register_operand" "w")
2359 (match_operand:VDQIW 2 "s_register_operand" "w")
2360 (match_operand:SI 3 "immediate_operand" "i")]
2363 "vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2364 [(set_attr "neon_type" "neon_int_5")]
2367 (define_insn "neon_vcgt<mode>"
2368 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2369 (unspec:<V_cmp_result>
2370 [(match_operand:VDQW 1 "s_register_operand" "w,w")
2371 (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2372 (match_operand:SI 3 "immediate_operand" "i,i")]
2376 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2377 vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2378 [(set (attr "neon_type")
2379 (if_then_else (match_test "<Is_float_mode>")
2380 (if_then_else (match_test "<Is_d_reg>")
2381 (const_string "neon_fp_vadd_ddd_vabs_dd")
2382 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2383 (const_string "neon_int_5")))]
2386 (define_insn "neon_vcgtu<mode>"
2387 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2388 (unspec:<V_cmp_result>
2389 [(match_operand:VDQIW 1 "s_register_operand" "w")
2390 (match_operand:VDQIW 2 "s_register_operand" "w")
2391 (match_operand:SI 3 "immediate_operand" "i")]
2394 "vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2395 [(set_attr "neon_type" "neon_int_5")]
2398 ;; VCLE and VCLT only support comparisons with immediate zero (register
2399 ;; variants are VCGE and VCGT with operands reversed).
2401 (define_insn "neon_vcle<mode>"
2402 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2403 (unspec:<V_cmp_result>
2404 [(match_operand:VDQW 1 "s_register_operand" "w")
2405 (match_operand:VDQW 2 "zero_operand" "Dz")
2406 (match_operand:SI 3 "immediate_operand" "i")]
2409 "vcle.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2410 [(set (attr "neon_type")
2411 (if_then_else (match_test "<Is_float_mode>")
2412 (if_then_else (match_test "<Is_d_reg>")
2413 (const_string "neon_fp_vadd_ddd_vabs_dd")
2414 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2415 (const_string "neon_int_5")))]
2418 (define_insn "neon_vclt<mode>"
2419 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2420 (unspec:<V_cmp_result>
2421 [(match_operand:VDQW 1 "s_register_operand" "w")
2422 (match_operand:VDQW 2 "zero_operand" "Dz")
2423 (match_operand:SI 3 "immediate_operand" "i")]
2426 "vclt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2427 [(set (attr "neon_type")
2428 (if_then_else (match_test "<Is_float_mode>")
2429 (if_then_else (match_test "<Is_d_reg>")
2430 (const_string "neon_fp_vadd_ddd_vabs_dd")
2431 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2432 (const_string "neon_int_5")))]
2435 (define_insn "neon_vcage<mode>"
2436 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2437 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2438 (match_operand:VCVTF 2 "s_register_operand" "w")
2439 (match_operand:SI 3 "immediate_operand" "i")]
2442 "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2443 [(set (attr "neon_type")
2444 (if_then_else (match_test "<Is_d_reg>")
2445 (const_string "neon_fp_vadd_ddd_vabs_dd")
2446 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2449 (define_insn "neon_vcagt<mode>"
2450 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2451 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2452 (match_operand:VCVTF 2 "s_register_operand" "w")
2453 (match_operand:SI 3 "immediate_operand" "i")]
2456 "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2457 [(set (attr "neon_type")
2458 (if_then_else (match_test "<Is_d_reg>")
2459 (const_string "neon_fp_vadd_ddd_vabs_dd")
2460 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2463 (define_insn "neon_vtst<mode>"
2464 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2465 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2466 (match_operand:VDQIW 2 "s_register_operand" "w")
2467 (match_operand:SI 3 "immediate_operand" "i")]
2470 "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2471 [(set_attr "neon_type" "neon_int_4")]
2474 (define_insn "neon_vabd<mode>"
2475 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2476 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2477 (match_operand:VDQW 2 "s_register_operand" "w")
2478 (match_operand:SI 3 "immediate_operand" "i")]
2481 "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2482 [(set (attr "neon_type")
2483 (if_then_else (match_test "<Is_float_mode>")
2484 (if_then_else (match_test "<Is_d_reg>")
2485 (const_string "neon_fp_vadd_ddd_vabs_dd")
2486 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2487 (const_string "neon_int_5")))]
2490 (define_insn "neon_vabdl<mode>"
2491 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2492 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2493 (match_operand:VW 2 "s_register_operand" "w")
2494 (match_operand:SI 3 "immediate_operand" "i")]
2497 "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2498 [(set_attr "neon_type" "neon_int_5")]
2501 (define_insn "neon_vaba<mode>"
2502 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2503 (plus:VDQIW (unspec:VDQIW [(match_operand:VDQIW 2 "s_register_operand" "w")
2504 (match_operand:VDQIW 3 "s_register_operand" "w")
2505 (match_operand:SI 4 "immediate_operand" "i")]
2507 (match_operand:VDQIW 1 "s_register_operand" "0")))]
2509 "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2510 [(set (attr "neon_type")
2511 (if_then_else (match_test "<Is_d_reg>")
2512 (const_string "neon_vaba") (const_string "neon_vaba_qqq")))]
2515 (define_insn "neon_vabal<mode>"
2516 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2517 (plus:<V_widen> (unspec:<V_widen> [(match_operand:VW 2 "s_register_operand" "w")
2518 (match_operand:VW 3 "s_register_operand" "w")
2519 (match_operand:SI 4 "immediate_operand" "i")]
2521 (match_operand:<V_widen> 1 "s_register_operand" "0")))]
2523 "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2524 [(set_attr "neon_type" "neon_vaba")]
2527 (define_insn "neon_vmax<mode>"
2528 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2529 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2530 (match_operand:VDQW 2 "s_register_operand" "w")
2531 (match_operand:SI 3 "immediate_operand" "i")]
2534 "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2535 [(set (attr "neon_type")
2536 (if_then_else (match_test "<Is_float_mode>")
2537 (if_then_else (match_test "<Is_d_reg>")
2538 (const_string "neon_fp_vadd_ddd_vabs_dd")
2539 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2540 (const_string "neon_int_5")))]
2543 (define_insn "neon_vmin<mode>"
2544 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2545 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2546 (match_operand:VDQW 2 "s_register_operand" "w")
2547 (match_operand:SI 3 "immediate_operand" "i")]
2550 "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2551 [(set (attr "neon_type")
2552 (if_then_else (match_test "<Is_float_mode>")
2553 (if_then_else (match_test "<Is_d_reg>")
2554 (const_string "neon_fp_vadd_ddd_vabs_dd")
2555 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2556 (const_string "neon_int_5")))]
2559 (define_expand "neon_vpadd<mode>"
2560 [(match_operand:VD 0 "s_register_operand" "=w")
2561 (match_operand:VD 1 "s_register_operand" "w")
2562 (match_operand:VD 2 "s_register_operand" "w")
2563 (match_operand:SI 3 "immediate_operand" "i")]
2566 emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1],
2571 (define_insn "neon_vpaddl<mode>"
2572 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2573 (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")
2574 (match_operand:SI 2 "immediate_operand" "i")]
2577 "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2578 ;; Assume this schedules like vaddl.
2579 [(set_attr "neon_type" "neon_int_3")]
2582 (define_insn "neon_vpadal<mode>"
2583 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2584 (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0")
2585 (match_operand:VDQIW 2 "s_register_operand" "w")
2586 (match_operand:SI 3 "immediate_operand" "i")]
2589 "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
2590 ;; Assume this schedules like vpadd.
2591 [(set_attr "neon_type" "neon_int_1")]
2594 (define_insn "neon_vpmax<mode>"
2595 [(set (match_operand:VD 0 "s_register_operand" "=w")
2596 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2597 (match_operand:VD 2 "s_register_operand" "w")
2598 (match_operand:SI 3 "immediate_operand" "i")]
2601 "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2602 ;; Assume this schedules like vmax.
2603 [(set (attr "neon_type")
2604 (if_then_else (match_test "<Is_float_mode>")
2605 (const_string "neon_fp_vadd_ddd_vabs_dd")
2606 (const_string "neon_int_5")))]
2609 (define_insn "neon_vpmin<mode>"
2610 [(set (match_operand:VD 0 "s_register_operand" "=w")
2611 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2612 (match_operand:VD 2 "s_register_operand" "w")
2613 (match_operand:SI 3 "immediate_operand" "i")]
2616 "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2617 ;; Assume this schedules like vmin.
2618 [(set (attr "neon_type")
2619 (if_then_else (match_test "<Is_float_mode>")
2620 (const_string "neon_fp_vadd_ddd_vabs_dd")
2621 (const_string "neon_int_5")))]
2624 (define_insn "neon_vrecps<mode>"
2625 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2626 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2627 (match_operand:VCVTF 2 "s_register_operand" "w")
2628 (match_operand:SI 3 "immediate_operand" "i")]
2631 "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2632 [(set (attr "neon_type")
2633 (if_then_else (match_test "<Is_d_reg>")
2634 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2635 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2638 (define_insn "neon_vrsqrts<mode>"
2639 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2640 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2641 (match_operand:VCVTF 2 "s_register_operand" "w")
2642 (match_operand:SI 3 "immediate_operand" "i")]
2645 "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2646 [(set (attr "neon_type")
2647 (if_then_else (match_test "<Is_d_reg>")
2648 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2649 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2652 (define_expand "neon_vabs<mode>"
2653 [(match_operand:VDQW 0 "s_register_operand" "")
2654 (match_operand:VDQW 1 "s_register_operand" "")
2655 (match_operand:SI 2 "immediate_operand" "")]
2658 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
2662 (define_insn "neon_vqabs<mode>"
2663 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2664 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2665 (match_operand:SI 2 "immediate_operand" "i")]
2668 "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2669 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2672 (define_expand "neon_vneg<mode>"
2673 [(match_operand:VDQW 0 "s_register_operand" "")
2674 (match_operand:VDQW 1 "s_register_operand" "")
2675 (match_operand:SI 2 "immediate_operand" "")]
2678 emit_insn (gen_neg<mode>2 (operands[0], operands[1]));
2682 (define_insn "neon_vqneg<mode>"
2683 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2684 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2685 (match_operand:SI 2 "immediate_operand" "i")]
2688 "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2689 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2692 (define_insn "neon_vcls<mode>"
2693 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2694 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2695 (match_operand:SI 2 "immediate_operand" "i")]
2698 "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2699 [(set_attr "neon_type" "neon_int_1")]
2702 (define_insn "clz<mode>2"
2703 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2704 (clz:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")))]
2706 "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1"
2707 [(set_attr "neon_type" "neon_int_1")]
2710 (define_expand "neon_vclz<mode>"
2711 [(match_operand:VDQIW 0 "s_register_operand" "")
2712 (match_operand:VDQIW 1 "s_register_operand" "")
2713 (match_operand:SI 2 "immediate_operand" "")]
2716 emit_insn (gen_clz<mode>2 (operands[0], operands[1]));
2720 (define_insn "popcount<mode>2"
2721 [(set (match_operand:VE 0 "s_register_operand" "=w")
2722 (popcount:VE (match_operand:VE 1 "s_register_operand" "w")))]
2724 "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2725 [(set_attr "neon_type" "neon_int_1")]
2728 (define_expand "neon_vcnt<mode>"
2729 [(match_operand:VE 0 "s_register_operand" "=w")
2730 (match_operand:VE 1 "s_register_operand" "w")
2731 (match_operand:SI 2 "immediate_operand" "i")]
2734 emit_insn (gen_popcount<mode>2 (operands[0], operands[1]));
2738 (define_insn "neon_vrecpe<mode>"
2739 [(set (match_operand:V32 0 "s_register_operand" "=w")
2740 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2741 (match_operand:SI 2 "immediate_operand" "i")]
2744 "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2745 [(set (attr "neon_type")
2746 (if_then_else (match_test "<Is_d_reg>")
2747 (const_string "neon_fp_vadd_ddd_vabs_dd")
2748 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2751 (define_insn "neon_vrsqrte<mode>"
2752 [(set (match_operand:V32 0 "s_register_operand" "=w")
2753 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2754 (match_operand:SI 2 "immediate_operand" "i")]
2757 "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2758 [(set (attr "neon_type")
2759 (if_then_else (match_test "<Is_d_reg>")
2760 (const_string "neon_fp_vadd_ddd_vabs_dd")
2761 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2764 (define_expand "neon_vmvn<mode>"
2765 [(match_operand:VDQIW 0 "s_register_operand" "")
2766 (match_operand:VDQIW 1 "s_register_operand" "")
2767 (match_operand:SI 2 "immediate_operand" "")]
2770 emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1]));
2774 (define_insn "neon_vget_lane<mode>_sext_internal"
2775 [(set (match_operand:SI 0 "s_register_operand" "=r")
2777 (vec_select:<V_elem>
2778 (match_operand:VD 1 "s_register_operand" "w")
2779 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2782 if (BYTES_BIG_ENDIAN)
2784 int elt = INTVAL (operands[2]);
2785 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2786 operands[2] = GEN_INT (elt);
2788 return "vmov.s<V_sz_elem>\t%0, %P1[%c2]";
2790 [(set_attr "neon_type" "neon_bp_simple")]
2793 (define_insn "neon_vget_lane<mode>_zext_internal"
2794 [(set (match_operand:SI 0 "s_register_operand" "=r")
2796 (vec_select:<V_elem>
2797 (match_operand:VD 1 "s_register_operand" "w")
2798 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2801 if (BYTES_BIG_ENDIAN)
2803 int elt = INTVAL (operands[2]);
2804 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2805 operands[2] = GEN_INT (elt);
2807 return "vmov.u<V_sz_elem>\t%0, %P1[%c2]";
2809 [(set_attr "neon_type" "neon_bp_simple")]
2812 (define_insn "neon_vget_lane<mode>_sext_internal"
2813 [(set (match_operand:SI 0 "s_register_operand" "=r")
2815 (vec_select:<V_elem>
2816 (match_operand:VQ 1 "s_register_operand" "w")
2817 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2821 int regno = REGNO (operands[1]);
2822 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2823 unsigned int elt = INTVAL (operands[2]);
2824 unsigned int elt_adj = elt % halfelts;
2826 if (BYTES_BIG_ENDIAN)
2827 elt_adj = halfelts - 1 - elt_adj;
2829 ops[0] = operands[0];
2830 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2831 ops[2] = GEN_INT (elt_adj);
2832 output_asm_insn ("vmov.s<V_sz_elem>\t%0, %P1[%c2]", ops);
2836 [(set_attr "neon_type" "neon_bp_simple")]
2839 (define_insn "neon_vget_lane<mode>_zext_internal"
2840 [(set (match_operand:SI 0 "s_register_operand" "=r")
2842 (vec_select:<V_elem>
2843 (match_operand:VQ 1 "s_register_operand" "w")
2844 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2848 int regno = REGNO (operands[1]);
2849 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2850 unsigned int elt = INTVAL (operands[2]);
2851 unsigned int elt_adj = elt % halfelts;
2853 if (BYTES_BIG_ENDIAN)
2854 elt_adj = halfelts - 1 - elt_adj;
2856 ops[0] = operands[0];
2857 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2858 ops[2] = GEN_INT (elt_adj);
2859 output_asm_insn ("vmov.u<V_sz_elem>\t%0, %P1[%c2]", ops);
2863 [(set_attr "neon_type" "neon_bp_simple")]
2866 (define_expand "neon_vget_lane<mode>"
2867 [(match_operand:<V_ext> 0 "s_register_operand" "")
2868 (match_operand:VDQW 1 "s_register_operand" "")
2869 (match_operand:SI 2 "immediate_operand" "")
2870 (match_operand:SI 3 "immediate_operand" "")]
2873 HOST_WIDE_INT magic = INTVAL (operands[3]);
2876 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode));
2878 if (BYTES_BIG_ENDIAN)
2880 /* The intrinsics are defined in terms of a model where the
2881 element ordering in memory is vldm order, whereas the generic
2882 RTL is defined in terms of a model where the element ordering
2883 in memory is array order. Convert the lane number to conform
2885 unsigned int elt = INTVAL (operands[2]);
2886 unsigned int reg_nelts
2887 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2888 elt ^= reg_nelts - 1;
2889 operands[2] = GEN_INT (elt);
2892 if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32)
2893 insn = gen_vec_extract<mode> (operands[0], operands[1], operands[2]);
2896 if ((magic & 1) != 0)
2897 insn = gen_neon_vget_lane<mode>_sext_internal (operands[0], operands[1],
2900 insn = gen_neon_vget_lane<mode>_zext_internal (operands[0], operands[1],
2907 ; Operand 3 (info word) is ignored because it does nothing useful with 64-bit
2910 (define_expand "neon_vget_lanedi"
2911 [(match_operand:DI 0 "s_register_operand" "=r")
2912 (match_operand:DI 1 "s_register_operand" "w")
2913 (match_operand:SI 2 "immediate_operand" "i")
2914 (match_operand:SI 3 "immediate_operand" "i")]
2917 neon_lane_bounds (operands[2], 0, 1);
2918 emit_move_insn (operands[0], operands[1]);
2922 (define_expand "neon_vget_lanev2di"
2923 [(match_operand:DI 0 "s_register_operand" "")
2924 (match_operand:V2DI 1 "s_register_operand" "")
2925 (match_operand:SI 2 "immediate_operand" "")
2926 (match_operand:SI 3 "immediate_operand" "")]
2929 switch (INTVAL (operands[2]))
2932 emit_move_insn (operands[0], gen_lowpart (DImode, operands[1]));
2935 emit_move_insn (operands[0], gen_highpart (DImode, operands[1]));
2938 neon_lane_bounds (operands[2], 0, 1);
2944 (define_expand "neon_vset_lane<mode>"
2945 [(match_operand:VDQ 0 "s_register_operand" "=w")
2946 (match_operand:<V_elem> 1 "s_register_operand" "r")
2947 (match_operand:VDQ 2 "s_register_operand" "0")
2948 (match_operand:SI 3 "immediate_operand" "i")]
2951 unsigned int elt = INTVAL (operands[3]);
2952 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
2954 if (BYTES_BIG_ENDIAN)
2956 unsigned int reg_nelts
2957 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2958 elt ^= reg_nelts - 1;
2961 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
2962 GEN_INT (1 << elt), operands[2]));
2966 ; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
2968 (define_expand "neon_vset_lanedi"
2969 [(match_operand:DI 0 "s_register_operand" "=w")
2970 (match_operand:DI 1 "s_register_operand" "r")
2971 (match_operand:DI 2 "s_register_operand" "0")
2972 (match_operand:SI 3 "immediate_operand" "i")]
2975 neon_lane_bounds (operands[3], 0, 1);
2976 emit_move_insn (operands[0], operands[1]);
2980 (define_expand "neon_vcreate<mode>"
2981 [(match_operand:VDX 0 "s_register_operand" "")
2982 (match_operand:DI 1 "general_operand" "")]
2985 rtx src = gen_lowpart (<MODE>mode, operands[1]);
2986 emit_move_insn (operands[0], src);
2990 (define_insn "neon_vdup_n<mode>"
2991 [(set (match_operand:VX 0 "s_register_operand" "=w")
2992 (vec_duplicate:VX (match_operand:<V_elem> 1 "s_register_operand" "r")))]
2994 "vdup.<V_sz_elem>\t%<V_reg>0, %1"
2995 ;; Assume this schedules like vmov.
2996 [(set_attr "neon_type" "neon_bp_simple")]
2999 (define_insn "neon_vdup_n<mode>"
3000 [(set (match_operand:V32 0 "s_register_operand" "=w,w")
3001 (vec_duplicate:V32 (match_operand:<V_elem> 1 "s_register_operand" "r,t")))]
3004 vdup.<V_sz_elem>\t%<V_reg>0, %1
3005 vdup.<V_sz_elem>\t%<V_reg>0, %y1"
3006 ;; Assume this schedules like vmov.
3007 [(set_attr "neon_type" "neon_bp_simple")]
3010 (define_expand "neon_vdup_ndi"
3011 [(match_operand:DI 0 "s_register_operand" "=w")
3012 (match_operand:DI 1 "s_register_operand" "r")]
3015 emit_move_insn (operands[0], operands[1]);
3020 (define_insn "neon_vdup_nv2di"
3021 [(set (match_operand:V2DI 0 "s_register_operand" "=w,w")
3022 (vec_duplicate:V2DI (match_operand:DI 1 "s_register_operand" "r,w")))]
3025 vmov\t%e0, %Q1, %R1\;vmov\t%f0, %Q1, %R1
3026 vmov\t%e0, %P1\;vmov\t%f0, %P1"
3027 [(set_attr "length" "8")
3028 (set_attr "neon_type" "neon_bp_simple")]
3031 (define_insn "neon_vdup_lane<mode>_internal"
3032 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3034 (vec_select:<V_elem>
3035 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
3036 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
3039 if (BYTES_BIG_ENDIAN)
3041 int elt = INTVAL (operands[2]);
3042 elt = GET_MODE_NUNITS (<V_double_vector_mode>mode) - 1 - elt;
3043 operands[2] = GEN_INT (elt);
3046 return "vdup.<V_sz_elem>\t%P0, %P1[%c2]";
3048 return "vdup.<V_sz_elem>\t%q0, %P1[%c2]";
3050 ;; Assume this schedules like vmov.
3051 [(set_attr "neon_type" "neon_bp_simple")]
3054 (define_expand "neon_vdup_lane<mode>"
3055 [(match_operand:VDQW 0 "s_register_operand" "=w")
3056 (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
3057 (match_operand:SI 2 "immediate_operand" "i")]
3060 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<V_double_vector_mode>mode));
3061 if (BYTES_BIG_ENDIAN)
3063 unsigned int elt = INTVAL (operands[2]);
3064 unsigned int reg_nelts
3065 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<V_double_vector_mode>mode));
3066 elt ^= reg_nelts - 1;
3067 operands[2] = GEN_INT (elt);
3069 emit_insn (gen_neon_vdup_lane<mode>_internal (operands[0], operands[1],
3074 ; Scalar index is ignored, since only zero is valid here.
3075 (define_expand "neon_vdup_lanedi"
3076 [(match_operand:DI 0 "s_register_operand" "=w")
3077 (match_operand:DI 1 "s_register_operand" "w")
3078 (match_operand:SI 2 "immediate_operand" "i")]
3081 neon_lane_bounds (operands[2], 0, 1);
3082 emit_move_insn (operands[0], operands[1]);
3086 ; Likewise for v2di, as the DImode second operand has only a single element.
3087 (define_expand "neon_vdup_lanev2di"
3088 [(match_operand:V2DI 0 "s_register_operand" "=w")
3089 (match_operand:DI 1 "s_register_operand" "w")
3090 (match_operand:SI 2 "immediate_operand" "i")]
3093 neon_lane_bounds (operands[2], 0, 1);
3094 emit_insn (gen_neon_vdup_nv2di (operands[0], operands[1]));
3098 ; Disabled before reload because we don't want combine doing something silly,
3099 ; but used by the post-reload expansion of neon_vcombine.
3100 (define_insn "*neon_vswp<mode>"
3101 [(set (match_operand:VDQX 0 "s_register_operand" "+w")
3102 (match_operand:VDQX 1 "s_register_operand" "+w"))
3103 (set (match_dup 1) (match_dup 0))]
3104 "TARGET_NEON && reload_completed"
3105 "vswp\t%<V_reg>0, %<V_reg>1"
3106 [(set (attr "neon_type")
3107 (if_then_else (match_test "<Is_d_reg>")
3108 (const_string "neon_bp_simple")
3109 (const_string "neon_bp_2cycle")))]
3112 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
3114 ;; FIXME: A different implementation of this builtin could make it much
3115 ;; more likely that we wouldn't actually need to output anything (we could make
3116 ;; it so that the reg allocator puts things in the right places magically
3117 ;; instead). Lack of subregs for vectors makes that tricky though, I think.
3119 (define_insn_and_split "neon_vcombine<mode>"
3120 [(set (match_operand:<V_DOUBLE> 0 "s_register_operand" "=w")
3121 (vec_concat:<V_DOUBLE>
3122 (match_operand:VDX 1 "s_register_operand" "w")
3123 (match_operand:VDX 2 "s_register_operand" "w")))]
3126 "&& reload_completed"
3129 neon_split_vcombine (operands);
3133 (define_expand "neon_vget_high<mode>"
3134 [(match_operand:<V_HALF> 0 "s_register_operand")
3135 (match_operand:VQX 1 "s_register_operand")]
3138 emit_move_insn (operands[0],
3139 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode,
3140 GET_MODE_SIZE (<V_HALF>mode)));
3144 (define_expand "neon_vget_low<mode>"
3145 [(match_operand:<V_HALF> 0 "s_register_operand")
3146 (match_operand:VQX 1 "s_register_operand")]
3149 emit_move_insn (operands[0],
3150 simplify_gen_subreg (<V_HALF>mode, operands[1],
3155 (define_insn "float<mode><V_cvtto>2"
3156 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3157 (float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))]
3158 "TARGET_NEON && !flag_rounding_math"
3159 "vcvt.f32.s32\t%<V_reg>0, %<V_reg>1"
3160 [(set (attr "neon_type")
3161 (if_then_else (match_test "<Is_d_reg>")
3162 (const_string "neon_fp_vadd_ddd_vabs_dd")
3163 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3166 (define_insn "floatuns<mode><V_cvtto>2"
3167 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3168 (unsigned_float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))]
3169 "TARGET_NEON && !flag_rounding_math"
3170 "vcvt.f32.u32\t%<V_reg>0, %<V_reg>1"
3171 [(set (attr "neon_type")
3172 (if_then_else (match_test "<Is_d_reg>")
3173 (const_string "neon_fp_vadd_ddd_vabs_dd")
3174 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3177 (define_insn "fix_trunc<mode><V_cvtto>2"
3178 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3179 (fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))]
3181 "vcvt.s32.f32\t%<V_reg>0, %<V_reg>1"
3182 [(set (attr "neon_type")
3183 (if_then_else (match_test "<Is_d_reg>")
3184 (const_string "neon_fp_vadd_ddd_vabs_dd")
3185 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3188 (define_insn "fixuns_trunc<mode><V_cvtto>2"
3189 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3190 (unsigned_fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))]
3192 "vcvt.u32.f32\t%<V_reg>0, %<V_reg>1"
3193 [(set (attr "neon_type")
3194 (if_then_else (match_test "<Is_d_reg>")
3195 (const_string "neon_fp_vadd_ddd_vabs_dd")
3196 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3199 (define_insn "neon_vcvt<mode>"
3200 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3201 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3202 (match_operand:SI 2 "immediate_operand" "i")]
3205 "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1"
3206 [(set (attr "neon_type")
3207 (if_then_else (match_test "<Is_d_reg>")
3208 (const_string "neon_fp_vadd_ddd_vabs_dd")
3209 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3212 (define_insn "neon_vcvt<mode>"
3213 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3214 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3215 (match_operand:SI 2 "immediate_operand" "i")]
3218 "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1"
3219 [(set (attr "neon_type")
3220 (if_then_else (match_test "<Is_d_reg>")
3221 (const_string "neon_fp_vadd_ddd_vabs_dd")
3222 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3225 (define_insn "neon_vcvtv4sfv4hf"
3226 [(set (match_operand:V4SF 0 "s_register_operand" "=w")
3227 (unspec:V4SF [(match_operand:V4HF 1 "s_register_operand" "w")]
3229 "TARGET_NEON && TARGET_FP16"
3230 "vcvt.f32.f16\t%q0, %P1"
3231 [(set_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")]
3234 (define_insn "neon_vcvtv4hfv4sf"
3235 [(set (match_operand:V4HF 0 "s_register_operand" "=w")
3236 (unspec:V4HF [(match_operand:V4SF 1 "s_register_operand" "w")]
3238 "TARGET_NEON && TARGET_FP16"
3239 "vcvt.f16.f32\t%P0, %q1"
3240 [(set_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")]
3243 (define_insn "neon_vcvt_n<mode>"
3244 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3245 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3246 (match_operand:SI 2 "immediate_operand" "i")
3247 (match_operand:SI 3 "immediate_operand" "i")]
3251 neon_const_bounds (operands[2], 1, 33);
3252 return "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2";
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 "neon_vcvt_n<mode>"
3261 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3262 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3263 (match_operand:SI 2 "immediate_operand" "i")
3264 (match_operand:SI 3 "immediate_operand" "i")]
3268 neon_const_bounds (operands[2], 1, 33);
3269 return "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2";
3271 [(set (attr "neon_type")
3272 (if_then_else (match_test "<Is_d_reg>")
3273 (const_string "neon_fp_vadd_ddd_vabs_dd")
3274 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3277 (define_insn "neon_vmovn<mode>"
3278 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3279 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3280 (match_operand:SI 2 "immediate_operand" "i")]
3283 "vmovn.<V_if_elem>\t%P0, %q1"
3284 [(set_attr "neon_type" "neon_bp_simple")]
3287 (define_insn "neon_vqmovn<mode>"
3288 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3289 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3290 (match_operand:SI 2 "immediate_operand" "i")]
3293 "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1"
3294 [(set_attr "neon_type" "neon_shift_2")]
3297 (define_insn "neon_vqmovun<mode>"
3298 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3299 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3300 (match_operand:SI 2 "immediate_operand" "i")]
3303 "vqmovun.<V_s_elem>\t%P0, %q1"
3304 [(set_attr "neon_type" "neon_shift_2")]
3307 (define_insn "neon_vmovl<mode>"
3308 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3309 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
3310 (match_operand:SI 2 "immediate_operand" "i")]
3313 "vmovl.%T2%#<V_sz_elem>\t%q0, %P1"
3314 [(set_attr "neon_type" "neon_shift_1")]
3317 (define_insn "neon_vmul_lane<mode>"
3318 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3319 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
3320 (match_operand:VMD 2 "s_register_operand"
3321 "<scalar_mul_constraint>")
3322 (match_operand:SI 3 "immediate_operand" "i")
3323 (match_operand:SI 4 "immediate_operand" "i")]
3327 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3328 return "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]";
3330 [(set (attr "neon_type")
3331 (if_then_else (match_test "<Is_float_mode>")
3332 (const_string "neon_fp_vmul_ddd")
3333 (if_then_else (match_test "<Scalar_mul_8_16>")
3334 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3335 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))))]
3338 (define_insn "neon_vmul_lane<mode>"
3339 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3340 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
3341 (match_operand:<V_HALF> 2 "s_register_operand"
3342 "<scalar_mul_constraint>")
3343 (match_operand:SI 3 "immediate_operand" "i")
3344 (match_operand:SI 4 "immediate_operand" "i")]
3348 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<V_HALF>mode));
3349 return "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]";
3351 [(set (attr "neon_type")
3352 (if_then_else (match_test "<Is_float_mode>")
3353 (const_string "neon_fp_vmul_qqd")
3354 (if_then_else (match_test "<Scalar_mul_8_16>")
3355 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3356 (const_string "neon_mul_qqd_32_scalar"))))]
3359 (define_insn "neon_vmull_lane<mode>"
3360 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3361 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3362 (match_operand:VMDI 2 "s_register_operand"
3363 "<scalar_mul_constraint>")
3364 (match_operand:SI 3 "immediate_operand" "i")
3365 (match_operand:SI 4 "immediate_operand" "i")]
3366 UNSPEC_VMULL_LANE))]
3369 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3370 return "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]";
3372 [(set (attr "neon_type")
3373 (if_then_else (match_test "<Scalar_mul_8_16>")
3374 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3375 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3378 (define_insn "neon_vqdmull_lane<mode>"
3379 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3380 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3381 (match_operand:VMDI 2 "s_register_operand"
3382 "<scalar_mul_constraint>")
3383 (match_operand:SI 3 "immediate_operand" "i")
3384 (match_operand:SI 4 "immediate_operand" "i")]
3385 UNSPEC_VQDMULL_LANE))]
3388 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3389 return "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]";
3391 [(set (attr "neon_type")
3392 (if_then_else (match_test "<Scalar_mul_8_16>")
3393 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3394 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3397 (define_insn "neon_vqdmulh_lane<mode>"
3398 [(set (match_operand:VMQI 0 "s_register_operand" "=w")
3399 (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
3400 (match_operand:<V_HALF> 2 "s_register_operand"
3401 "<scalar_mul_constraint>")
3402 (match_operand:SI 3 "immediate_operand" "i")
3403 (match_operand:SI 4 "immediate_operand" "i")]
3404 UNSPEC_VQDMULH_LANE))]
3407 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3408 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]";
3410 [(set (attr "neon_type")
3411 (if_then_else (match_test "<Scalar_mul_8_16>")
3412 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3413 (const_string "neon_mul_qqd_32_scalar")))]
3416 (define_insn "neon_vqdmulh_lane<mode>"
3417 [(set (match_operand:VMDI 0 "s_register_operand" "=w")
3418 (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
3419 (match_operand:VMDI 2 "s_register_operand"
3420 "<scalar_mul_constraint>")
3421 (match_operand:SI 3 "immediate_operand" "i")
3422 (match_operand:SI 4 "immediate_operand" "i")]
3423 UNSPEC_VQDMULH_LANE))]
3426 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3427 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]";
3429 [(set (attr "neon_type")
3430 (if_then_else (match_test "<Scalar_mul_8_16>")
3431 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3432 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3435 (define_insn "neon_vmla_lane<mode>"
3436 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3437 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3438 (match_operand:VMD 2 "s_register_operand" "w")
3439 (match_operand:VMD 3 "s_register_operand"
3440 "<scalar_mul_constraint>")
3441 (match_operand:SI 4 "immediate_operand" "i")
3442 (match_operand:SI 5 "immediate_operand" "i")]
3446 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3447 return "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3449 [(set (attr "neon_type")
3450 (if_then_else (match_test "<Is_float_mode>")
3451 (const_string "neon_fp_vmla_ddd_scalar")
3452 (if_then_else (match_test "<Scalar_mul_8_16>")
3453 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3454 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3457 (define_insn "neon_vmla_lane<mode>"
3458 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3459 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3460 (match_operand:VMQ 2 "s_register_operand" "w")
3461 (match_operand:<V_HALF> 3 "s_register_operand"
3462 "<scalar_mul_constraint>")
3463 (match_operand:SI 4 "immediate_operand" "i")
3464 (match_operand:SI 5 "immediate_operand" "i")]
3468 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3469 return "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3471 [(set (attr "neon_type")
3472 (if_then_else (match_test "<Is_float_mode>")
3473 (const_string "neon_fp_vmla_qqq_scalar")
3474 (if_then_else (match_test "<Scalar_mul_8_16>")
3475 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3476 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3479 (define_insn "neon_vmlal_lane<mode>"
3480 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3481 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3482 (match_operand:VMDI 2 "s_register_operand" "w")
3483 (match_operand:VMDI 3 "s_register_operand"
3484 "<scalar_mul_constraint>")
3485 (match_operand:SI 4 "immediate_operand" "i")
3486 (match_operand:SI 5 "immediate_operand" "i")]
3487 UNSPEC_VMLAL_LANE))]
3490 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3491 return "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3493 [(set (attr "neon_type")
3494 (if_then_else (match_test "<Scalar_mul_8_16>")
3495 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3496 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3499 (define_insn "neon_vqdmlal_lane<mode>"
3500 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3501 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3502 (match_operand:VMDI 2 "s_register_operand" "w")
3503 (match_operand:VMDI 3 "s_register_operand"
3504 "<scalar_mul_constraint>")
3505 (match_operand:SI 4 "immediate_operand" "i")
3506 (match_operand:SI 5 "immediate_operand" "i")]
3507 UNSPEC_VQDMLAL_LANE))]
3510 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3511 return "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3513 [(set (attr "neon_type")
3514 (if_then_else (match_test "<Scalar_mul_8_16>")
3515 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3516 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3519 (define_insn "neon_vmls_lane<mode>"
3520 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3521 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3522 (match_operand:VMD 2 "s_register_operand" "w")
3523 (match_operand:VMD 3 "s_register_operand"
3524 "<scalar_mul_constraint>")
3525 (match_operand:SI 4 "immediate_operand" "i")
3526 (match_operand:SI 5 "immediate_operand" "i")]
3530 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3531 return "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3533 [(set (attr "neon_type")
3534 (if_then_else (match_test "<Is_float_mode>")
3535 (const_string "neon_fp_vmla_ddd_scalar")
3536 (if_then_else (match_test "<Scalar_mul_8_16>")
3537 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3538 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3541 (define_insn "neon_vmls_lane<mode>"
3542 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3543 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3544 (match_operand:VMQ 2 "s_register_operand" "w")
3545 (match_operand:<V_HALF> 3 "s_register_operand"
3546 "<scalar_mul_constraint>")
3547 (match_operand:SI 4 "immediate_operand" "i")
3548 (match_operand:SI 5 "immediate_operand" "i")]
3552 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3553 return "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3555 [(set (attr "neon_type")
3556 (if_then_else (match_test "<Is_float_mode>")
3557 (const_string "neon_fp_vmla_qqq_scalar")
3558 (if_then_else (match_test "<Scalar_mul_8_16>")
3559 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3560 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3563 (define_insn "neon_vmlsl_lane<mode>"
3564 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3565 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3566 (match_operand:VMDI 2 "s_register_operand" "w")
3567 (match_operand:VMDI 3 "s_register_operand"
3568 "<scalar_mul_constraint>")
3569 (match_operand:SI 4 "immediate_operand" "i")
3570 (match_operand:SI 5 "immediate_operand" "i")]
3571 UNSPEC_VMLSL_LANE))]
3574 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3575 return "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3577 [(set (attr "neon_type")
3578 (if_then_else (match_test "<Scalar_mul_8_16>")
3579 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3580 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3583 (define_insn "neon_vqdmlsl_lane<mode>"
3584 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3585 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3586 (match_operand:VMDI 2 "s_register_operand" "w")
3587 (match_operand:VMDI 3 "s_register_operand"
3588 "<scalar_mul_constraint>")
3589 (match_operand:SI 4 "immediate_operand" "i")
3590 (match_operand:SI 5 "immediate_operand" "i")]
3591 UNSPEC_VQDMLSL_LANE))]
3594 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3595 return "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3597 [(set (attr "neon_type")
3598 (if_then_else (match_test "<Scalar_mul_8_16>")
3599 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3600 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3603 ; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
3604 ; core register into a temp register, then use a scalar taken from that. This
3605 ; isn't an optimal solution if e.g. the scalar has just been read from memory
3606 ; or extracted from another vector. The latter case it's currently better to
3607 ; use the "_lane" variant, and the former case can probably be implemented
3608 ; using vld1_lane, but that hasn't been done yet.
3610 (define_expand "neon_vmul_n<mode>"
3611 [(match_operand:VMD 0 "s_register_operand" "")
3612 (match_operand:VMD 1 "s_register_operand" "")
3613 (match_operand:<V_elem> 2 "s_register_operand" "")
3614 (match_operand:SI 3 "immediate_operand" "")]
3617 rtx tmp = gen_reg_rtx (<MODE>mode);
3618 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3619 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3620 const0_rtx, const0_rtx));
3624 (define_expand "neon_vmul_n<mode>"
3625 [(match_operand:VMQ 0 "s_register_operand" "")
3626 (match_operand:VMQ 1 "s_register_operand" "")
3627 (match_operand:<V_elem> 2 "s_register_operand" "")
3628 (match_operand:SI 3 "immediate_operand" "")]
3631 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3632 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3633 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3634 const0_rtx, const0_rtx));
3638 (define_expand "neon_vmull_n<mode>"
3639 [(match_operand:<V_widen> 0 "s_register_operand" "")
3640 (match_operand:VMDI 1 "s_register_operand" "")
3641 (match_operand:<V_elem> 2 "s_register_operand" "")
3642 (match_operand:SI 3 "immediate_operand" "")]
3645 rtx tmp = gen_reg_rtx (<MODE>mode);
3646 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3647 emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp,
3648 const0_rtx, operands[3]));
3652 (define_expand "neon_vqdmull_n<mode>"
3653 [(match_operand:<V_widen> 0 "s_register_operand" "")
3654 (match_operand:VMDI 1 "s_register_operand" "")
3655 (match_operand:<V_elem> 2 "s_register_operand" "")
3656 (match_operand:SI 3 "immediate_operand" "")]
3659 rtx tmp = gen_reg_rtx (<MODE>mode);
3660 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3661 emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp,
3662 const0_rtx, const0_rtx));
3666 (define_expand "neon_vqdmulh_n<mode>"
3667 [(match_operand:VMDI 0 "s_register_operand" "")
3668 (match_operand:VMDI 1 "s_register_operand" "")
3669 (match_operand:<V_elem> 2 "s_register_operand" "")
3670 (match_operand:SI 3 "immediate_operand" "")]
3673 rtx tmp = gen_reg_rtx (<MODE>mode);
3674 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3675 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3676 const0_rtx, operands[3]));
3680 (define_expand "neon_vqdmulh_n<mode>"
3681 [(match_operand:VMQI 0 "s_register_operand" "")
3682 (match_operand:VMQI 1 "s_register_operand" "")
3683 (match_operand:<V_elem> 2 "s_register_operand" "")
3684 (match_operand:SI 3 "immediate_operand" "")]
3687 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3688 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3689 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3690 const0_rtx, operands[3]));
3694 (define_expand "neon_vmla_n<mode>"
3695 [(match_operand:VMD 0 "s_register_operand" "")
3696 (match_operand:VMD 1 "s_register_operand" "")
3697 (match_operand:VMD 2 "s_register_operand" "")
3698 (match_operand:<V_elem> 3 "s_register_operand" "")
3699 (match_operand:SI 4 "immediate_operand" "")]
3702 rtx tmp = gen_reg_rtx (<MODE>mode);
3703 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3704 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3705 tmp, const0_rtx, operands[4]));
3709 (define_expand "neon_vmla_n<mode>"
3710 [(match_operand:VMQ 0 "s_register_operand" "")
3711 (match_operand:VMQ 1 "s_register_operand" "")
3712 (match_operand:VMQ 2 "s_register_operand" "")
3713 (match_operand:<V_elem> 3 "s_register_operand" "")
3714 (match_operand:SI 4 "immediate_operand" "")]
3717 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3718 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3719 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3720 tmp, const0_rtx, operands[4]));
3724 (define_expand "neon_vmlal_n<mode>"
3725 [(match_operand:<V_widen> 0 "s_register_operand" "")
3726 (match_operand:<V_widen> 1 "s_register_operand" "")
3727 (match_operand:VMDI 2 "s_register_operand" "")
3728 (match_operand:<V_elem> 3 "s_register_operand" "")
3729 (match_operand:SI 4 "immediate_operand" "")]
3732 rtx tmp = gen_reg_rtx (<MODE>mode);
3733 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3734 emit_insn (gen_neon_vmlal_lane<mode> (operands[0], operands[1], operands[2],
3735 tmp, const0_rtx, operands[4]));
3739 (define_expand "neon_vqdmlal_n<mode>"
3740 [(match_operand:<V_widen> 0 "s_register_operand" "")
3741 (match_operand:<V_widen> 1 "s_register_operand" "")
3742 (match_operand:VMDI 2 "s_register_operand" "")
3743 (match_operand:<V_elem> 3 "s_register_operand" "")
3744 (match_operand:SI 4 "immediate_operand" "")]
3747 rtx tmp = gen_reg_rtx (<MODE>mode);
3748 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3749 emit_insn (gen_neon_vqdmlal_lane<mode> (operands[0], operands[1], operands[2],
3750 tmp, const0_rtx, operands[4]));
3754 (define_expand "neon_vmls_n<mode>"
3755 [(match_operand:VMD 0 "s_register_operand" "")
3756 (match_operand:VMD 1 "s_register_operand" "")
3757 (match_operand:VMD 2 "s_register_operand" "")
3758 (match_operand:<V_elem> 3 "s_register_operand" "")
3759 (match_operand:SI 4 "immediate_operand" "")]
3762 rtx tmp = gen_reg_rtx (<MODE>mode);
3763 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3764 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3765 tmp, const0_rtx, operands[4]));
3769 (define_expand "neon_vmls_n<mode>"
3770 [(match_operand:VMQ 0 "s_register_operand" "")
3771 (match_operand:VMQ 1 "s_register_operand" "")
3772 (match_operand:VMQ 2 "s_register_operand" "")
3773 (match_operand:<V_elem> 3 "s_register_operand" "")
3774 (match_operand:SI 4 "immediate_operand" "")]
3777 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3778 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3779 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3780 tmp, const0_rtx, operands[4]));
3784 (define_expand "neon_vmlsl_n<mode>"
3785 [(match_operand:<V_widen> 0 "s_register_operand" "")
3786 (match_operand:<V_widen> 1 "s_register_operand" "")
3787 (match_operand:VMDI 2 "s_register_operand" "")
3788 (match_operand:<V_elem> 3 "s_register_operand" "")
3789 (match_operand:SI 4 "immediate_operand" "")]
3792 rtx tmp = gen_reg_rtx (<MODE>mode);
3793 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3794 emit_insn (gen_neon_vmlsl_lane<mode> (operands[0], operands[1], operands[2],
3795 tmp, const0_rtx, operands[4]));
3799 (define_expand "neon_vqdmlsl_n<mode>"
3800 [(match_operand:<V_widen> 0 "s_register_operand" "")
3801 (match_operand:<V_widen> 1 "s_register_operand" "")
3802 (match_operand:VMDI 2 "s_register_operand" "")
3803 (match_operand:<V_elem> 3 "s_register_operand" "")
3804 (match_operand:SI 4 "immediate_operand" "")]
3807 rtx tmp = gen_reg_rtx (<MODE>mode);
3808 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3809 emit_insn (gen_neon_vqdmlsl_lane<mode> (operands[0], operands[1], operands[2],
3810 tmp, const0_rtx, operands[4]));
3814 (define_insn "neon_vext<mode>"
3815 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
3816 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
3817 (match_operand:VDQX 2 "s_register_operand" "w")
3818 (match_operand:SI 3 "immediate_operand" "i")]
3822 neon_const_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3823 return "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3";
3825 [(set (attr "neon_type")
3826 (if_then_else (match_test "<Is_d_reg>")
3827 (const_string "neon_bp_simple")
3828 (const_string "neon_bp_2cycle")))]
3831 (define_insn "neon_vrev64<mode>"
3832 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
3833 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
3834 (match_operand:SI 2 "immediate_operand" "i")]
3837 "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3838 [(set_attr "neon_type" "neon_bp_simple")]
3841 (define_insn "neon_vrev32<mode>"
3842 [(set (match_operand:VX 0 "s_register_operand" "=w")
3843 (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")
3844 (match_operand:SI 2 "immediate_operand" "i")]
3847 "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3848 [(set_attr "neon_type" "neon_bp_simple")]
3851 (define_insn "neon_vrev16<mode>"
3852 [(set (match_operand:VE 0 "s_register_operand" "=w")
3853 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
3854 (match_operand:SI 2 "immediate_operand" "i")]
3857 "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3858 [(set_attr "neon_type" "neon_bp_simple")]
3861 ; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
3862 ; allocation. For an intrinsic of form:
3863 ; rD = vbsl_* (rS, rN, rM)
3864 ; We can use any of:
3865 ; vbsl rS, rN, rM (if D = S)
3866 ; vbit rD, rN, rS (if D = M, so 1-bits in rS choose bits from rN, else rM)
3867 ; vbif rD, rM, rS (if D = N, so 0-bits in rS choose bits from rM, else rN)
3869 (define_insn "neon_vbsl<mode>_internal"
3870 [(set (match_operand:VDQX 0 "s_register_operand" "=w,w,w")
3871 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" " 0,w,w")
3872 (match_operand:VDQX 2 "s_register_operand" " w,w,0")
3873 (match_operand:VDQX 3 "s_register_operand" " w,0,w")]
3877 vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3
3878 vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1
3879 vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1"
3880 [(set_attr "neon_type" "neon_int_1")]
3883 (define_expand "neon_vbsl<mode>"
3884 [(set (match_operand:VDQX 0 "s_register_operand" "")
3885 (unspec:VDQX [(match_operand:<V_cmp_result> 1 "s_register_operand" "")
3886 (match_operand:VDQX 2 "s_register_operand" "")
3887 (match_operand:VDQX 3 "s_register_operand" "")]
3891 /* We can't alias operands together if they have different modes. */
3892 operands[1] = gen_lowpart (<MODE>mode, operands[1]);
3895 (define_insn "neon_vshl<mode>"
3896 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3897 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3898 (match_operand:VDQIX 2 "s_register_operand" "w")
3899 (match_operand:SI 3 "immediate_operand" "i")]
3902 "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3903 [(set (attr "neon_type")
3904 (if_then_else (match_test "<Is_d_reg>")
3905 (const_string "neon_vshl_ddd")
3906 (const_string "neon_shift_3")))]
3909 (define_insn "neon_vqshl<mode>"
3910 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3911 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3912 (match_operand:VDQIX 2 "s_register_operand" "w")
3913 (match_operand:SI 3 "immediate_operand" "i")]
3916 "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3917 [(set (attr "neon_type")
3918 (if_then_else (match_test "<Is_d_reg>")
3919 (const_string "neon_shift_2")
3920 (const_string "neon_vqshl_vrshl_vqrshl_qqq")))]
3923 (define_insn "neon_vshr_n<mode>"
3924 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3925 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3926 (match_operand:SI 2 "immediate_operand" "i")
3927 (match_operand:SI 3 "immediate_operand" "i")]
3931 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) + 1);
3932 return "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3934 [(set_attr "neon_type" "neon_shift_1")]
3937 (define_insn "neon_vshrn_n<mode>"
3938 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3939 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3940 (match_operand:SI 2 "immediate_operand" "i")
3941 (match_operand:SI 3 "immediate_operand" "i")]
3945 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3946 return "v%O3shrn.<V_if_elem>\t%P0, %q1, %2";
3948 [(set_attr "neon_type" "neon_shift_1")]
3951 (define_insn "neon_vqshrn_n<mode>"
3952 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3953 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3954 (match_operand:SI 2 "immediate_operand" "i")
3955 (match_operand:SI 3 "immediate_operand" "i")]
3959 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3960 return "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3962 [(set_attr "neon_type" "neon_shift_2")]
3965 (define_insn "neon_vqshrun_n<mode>"
3966 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3967 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3968 (match_operand:SI 2 "immediate_operand" "i")
3969 (match_operand:SI 3 "immediate_operand" "i")]
3973 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3974 return "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3976 [(set_attr "neon_type" "neon_shift_2")]
3979 (define_insn "neon_vshl_n<mode>"
3980 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3981 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3982 (match_operand:SI 2 "immediate_operand" "i")
3983 (match_operand:SI 3 "immediate_operand" "i")]
3987 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3988 return "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2";
3990 [(set_attr "neon_type" "neon_shift_1")]
3993 (define_insn "neon_vqshl_n<mode>"
3994 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3995 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3996 (match_operand:SI 2 "immediate_operand" "i")
3997 (match_operand:SI 3 "immediate_operand" "i")]
4001 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
4002 return "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
4004 [(set_attr "neon_type" "neon_shift_2")]
4007 (define_insn "neon_vqshlu_n<mode>"
4008 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4009 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
4010 (match_operand:SI 2 "immediate_operand" "i")
4011 (match_operand:SI 3 "immediate_operand" "i")]
4015 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
4016 return "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
4018 [(set_attr "neon_type" "neon_shift_2")]
4021 (define_insn "neon_vshll_n<mode>"
4022 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
4023 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
4024 (match_operand:SI 2 "immediate_operand" "i")
4025 (match_operand:SI 3 "immediate_operand" "i")]
4029 /* The boundaries are: 0 < imm <= size. */
4030 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode) + 1);
4031 return "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2";
4033 [(set_attr "neon_type" "neon_shift_1")]
4036 (define_insn "neon_vsra_n<mode>"
4037 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4038 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4039 (match_operand:VDQIX 2 "s_register_operand" "w")
4040 (match_operand:SI 3 "immediate_operand" "i")
4041 (match_operand:SI 4 "immediate_operand" "i")]
4045 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
4046 return "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4048 [(set_attr "neon_type" "neon_vsra_vrsra")]
4051 (define_insn "neon_vsri_n<mode>"
4052 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4053 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4054 (match_operand:VDQIX 2 "s_register_operand" "w")
4055 (match_operand:SI 3 "immediate_operand" "i")]
4059 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
4060 return "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4062 [(set (attr "neon_type")
4063 (if_then_else (match_test "<Is_d_reg>")
4064 (const_string "neon_shift_1")
4065 (const_string "neon_shift_3")))]
4068 (define_insn "neon_vsli_n<mode>"
4069 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4070 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4071 (match_operand:VDQIX 2 "s_register_operand" "w")
4072 (match_operand:SI 3 "immediate_operand" "i")]
4076 neon_const_bounds (operands[3], 0, neon_element_bits (<MODE>mode));
4077 return "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4079 [(set (attr "neon_type")
4080 (if_then_else (match_test "<Is_d_reg>")
4081 (const_string "neon_shift_1")
4082 (const_string "neon_shift_3")))]
4085 (define_insn "neon_vtbl1v8qi"
4086 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4087 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")
4088 (match_operand:V8QI 2 "s_register_operand" "w")]
4091 "vtbl.8\t%P0, {%P1}, %P2"
4092 [(set_attr "neon_type" "neon_bp_2cycle")]
4095 (define_insn "neon_vtbl2v8qi"
4096 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4097 (unspec:V8QI [(match_operand:TI 1 "s_register_operand" "w")
4098 (match_operand:V8QI 2 "s_register_operand" "w")]
4103 int tabbase = REGNO (operands[1]);
4105 ops[0] = operands[0];
4106 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4107 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4108 ops[3] = operands[2];
4109 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2}, %P3", ops);
4113 [(set_attr "neon_type" "neon_bp_2cycle")]
4116 (define_insn "neon_vtbl3v8qi"
4117 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4118 (unspec:V8QI [(match_operand:EI 1 "s_register_operand" "w")
4119 (match_operand:V8QI 2 "s_register_operand" "w")]
4124 int tabbase = REGNO (operands[1]);
4126 ops[0] = operands[0];
4127 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4128 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4129 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4130 ops[4] = operands[2];
4131 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
4135 [(set_attr "neon_type" "neon_bp_3cycle")]
4138 (define_insn "neon_vtbl4v8qi"
4139 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4140 (unspec:V8QI [(match_operand:OI 1 "s_register_operand" "w")
4141 (match_operand:V8QI 2 "s_register_operand" "w")]
4146 int tabbase = REGNO (operands[1]);
4148 ops[0] = operands[0];
4149 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4150 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4151 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4152 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4153 ops[5] = operands[2];
4154 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4158 [(set_attr "neon_type" "neon_bp_3cycle")]
4161 ;; These three are used by the vec_perm infrastructure for V16QImode.
4162 (define_insn_and_split "neon_vtbl1v16qi"
4163 [(set (match_operand:V16QI 0 "s_register_operand" "=&w")
4164 (unspec:V16QI [(match_operand:V16QI 1 "s_register_operand" "w")
4165 (match_operand:V16QI 2 "s_register_operand" "w")]
4169 "&& reload_completed"
4172 rtx op0, op1, op2, part0, part2;
4176 op1 = gen_lowpart (TImode, operands[1]);
4179 ofs = subreg_lowpart_offset (V8QImode, V16QImode);
4180 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4181 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4182 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4184 ofs = subreg_highpart_offset (V8QImode, V16QImode);
4185 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4186 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4187 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4191 (define_insn_and_split "neon_vtbl2v16qi"
4192 [(set (match_operand:V16QI 0 "s_register_operand" "=&w")
4193 (unspec:V16QI [(match_operand:OI 1 "s_register_operand" "w")
4194 (match_operand:V16QI 2 "s_register_operand" "w")]
4198 "&& reload_completed"
4201 rtx op0, op1, op2, part0, part2;
4208 ofs = subreg_lowpart_offset (V8QImode, V16QImode);
4209 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4210 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4211 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4213 ofs = subreg_highpart_offset (V8QImode, V16QImode);
4214 part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4215 part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4216 emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4220 ;; ??? Logically we should extend the regular neon_vcombine pattern to
4221 ;; handle quad-word input modes, producing octa-word output modes. But
4222 ;; that requires us to add support for octa-word vector modes in moves.
4223 ;; That seems overkill for this one use in vec_perm.
4224 (define_insn_and_split "neon_vcombinev16qi"
4225 [(set (match_operand:OI 0 "s_register_operand" "=w")
4226 (unspec:OI [(match_operand:V16QI 1 "s_register_operand" "w")
4227 (match_operand:V16QI 2 "s_register_operand" "w")]
4231 "&& reload_completed"
4234 neon_split_vcombine (operands);
4238 (define_insn "neon_vtbx1v8qi"
4239 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4240 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4241 (match_operand:V8QI 2 "s_register_operand" "w")
4242 (match_operand:V8QI 3 "s_register_operand" "w")]
4245 "vtbx.8\t%P0, {%P2}, %P3"
4246 [(set_attr "neon_type" "neon_bp_2cycle")]
4249 (define_insn "neon_vtbx2v8qi"
4250 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4251 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4252 (match_operand:TI 2 "s_register_operand" "w")
4253 (match_operand:V8QI 3 "s_register_operand" "w")]
4258 int tabbase = REGNO (operands[2]);
4260 ops[0] = operands[0];
4261 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4262 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4263 ops[3] = operands[3];
4264 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2}, %P3", ops);
4268 [(set_attr "neon_type" "neon_bp_2cycle")]
4271 (define_insn "neon_vtbx3v8qi"
4272 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4273 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4274 (match_operand:EI 2 "s_register_operand" "w")
4275 (match_operand:V8QI 3 "s_register_operand" "w")]
4280 int tabbase = REGNO (operands[2]);
4282 ops[0] = operands[0];
4283 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4284 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4285 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4286 ops[4] = operands[3];
4287 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
4291 [(set_attr "neon_type" "neon_bp_3cycle")]
4294 (define_insn "neon_vtbx4v8qi"
4295 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4296 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4297 (match_operand:OI 2 "s_register_operand" "w")
4298 (match_operand:V8QI 3 "s_register_operand" "w")]
4303 int tabbase = REGNO (operands[2]);
4305 ops[0] = operands[0];
4306 ops[1] = gen_rtx_REG (V8QImode, tabbase);
4307 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4308 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4309 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4310 ops[5] = operands[3];
4311 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4315 [(set_attr "neon_type" "neon_bp_3cycle")]
4318 (define_expand "neon_vtrn<mode>_internal"
4320 [(set (match_operand:VDQW 0 "s_register_operand" "")
4321 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4322 (match_operand:VDQW 2 "s_register_operand" "")]
4324 (set (match_operand:VDQW 3 "s_register_operand" "")
4325 (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VTRN2))])]
4330 ;; Note: Different operand numbering to handle tied registers correctly.
4331 (define_insn "*neon_vtrn<mode>_insn"
4332 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4333 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4334 (match_operand:VDQW 3 "s_register_operand" "2")]
4336 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4337 (unspec:VDQW [(match_dup 1) (match_dup 3)]
4340 "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4341 [(set (attr "neon_type")
4342 (if_then_else (match_test "<Is_d_reg>")
4343 (const_string "neon_bp_simple")
4344 (const_string "neon_bp_3cycle")))]
4347 (define_expand "neon_vtrn<mode>"
4348 [(match_operand:SI 0 "s_register_operand" "r")
4349 (match_operand:VDQW 1 "s_register_operand" "w")
4350 (match_operand:VDQW 2 "s_register_operand" "w")]
4353 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vtrn<mode>_internal,
4354 operands[0], operands[1], operands[2]);
4358 (define_expand "neon_vzip<mode>_internal"
4360 [(set (match_operand:VDQW 0 "s_register_operand" "")
4361 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4362 (match_operand:VDQW 2 "s_register_operand" "")]
4364 (set (match_operand:VDQW 3 "s_register_operand" "")
4365 (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VZIP2))])]
4370 ;; Note: Different operand numbering to handle tied registers correctly.
4371 (define_insn "*neon_vzip<mode>_insn"
4372 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4373 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4374 (match_operand:VDQW 3 "s_register_operand" "2")]
4376 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4377 (unspec:VDQW [(match_dup 1) (match_dup 3)]
4380 "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4381 [(set (attr "neon_type")
4382 (if_then_else (match_test "<Is_d_reg>")
4383 (const_string "neon_bp_simple")
4384 (const_string "neon_bp_3cycle")))]
4387 (define_expand "neon_vzip<mode>"
4388 [(match_operand:SI 0 "s_register_operand" "r")
4389 (match_operand:VDQW 1 "s_register_operand" "w")
4390 (match_operand:VDQW 2 "s_register_operand" "w")]
4393 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vzip<mode>_internal,
4394 operands[0], operands[1], operands[2]);
4398 (define_expand "neon_vuzp<mode>_internal"
4400 [(set (match_operand:VDQW 0 "s_register_operand" "")
4401 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4402 (match_operand:VDQW 2 "s_register_operand" "")]
4404 (set (match_operand:VDQW 3 "s_register_operand" "")
4405 (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VUZP2))])]
4410 ;; Note: Different operand numbering to handle tied registers correctly.
4411 (define_insn "*neon_vuzp<mode>_insn"
4412 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4413 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4414 (match_operand:VDQW 3 "s_register_operand" "2")]
4416 (set (match_operand:VDQW 2 "s_register_operand" "=w")
4417 (unspec:VDQW [(match_dup 1) (match_dup 3)]
4420 "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4421 [(set (attr "neon_type")
4422 (if_then_else (match_test "<Is_d_reg>")
4423 (const_string "neon_bp_simple")
4424 (const_string "neon_bp_3cycle")))]
4427 (define_expand "neon_vuzp<mode>"
4428 [(match_operand:SI 0 "s_register_operand" "r")
4429 (match_operand:VDQW 1 "s_register_operand" "w")
4430 (match_operand:VDQW 2 "s_register_operand" "w")]
4433 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vuzp<mode>_internal,
4434 operands[0], operands[1], operands[2]);
4438 (define_expand "neon_vreinterpretv8qi<mode>"
4439 [(match_operand:V8QI 0 "s_register_operand" "")
4440 (match_operand:VDX 1 "s_register_operand" "")]
4443 neon_reinterpret (operands[0], operands[1]);
4447 (define_expand "neon_vreinterpretv4hi<mode>"
4448 [(match_operand:V4HI 0 "s_register_operand" "")
4449 (match_operand:VDX 1 "s_register_operand" "")]
4452 neon_reinterpret (operands[0], operands[1]);
4456 (define_expand "neon_vreinterpretv2si<mode>"
4457 [(match_operand:V2SI 0 "s_register_operand" "")
4458 (match_operand:VDX 1 "s_register_operand" "")]
4461 neon_reinterpret (operands[0], operands[1]);
4465 (define_expand "neon_vreinterpretv2sf<mode>"
4466 [(match_operand:V2SF 0 "s_register_operand" "")
4467 (match_operand:VDX 1 "s_register_operand" "")]
4470 neon_reinterpret (operands[0], operands[1]);
4474 (define_expand "neon_vreinterpretdi<mode>"
4475 [(match_operand:DI 0 "s_register_operand" "")
4476 (match_operand:VDX 1 "s_register_operand" "")]
4479 neon_reinterpret (operands[0], operands[1]);
4483 (define_expand "neon_vreinterpretv16qi<mode>"
4484 [(match_operand:V16QI 0 "s_register_operand" "")
4485 (match_operand:VQX 1 "s_register_operand" "")]
4488 neon_reinterpret (operands[0], operands[1]);
4492 (define_expand "neon_vreinterpretv8hi<mode>"
4493 [(match_operand:V8HI 0 "s_register_operand" "")
4494 (match_operand:VQX 1 "s_register_operand" "")]
4497 neon_reinterpret (operands[0], operands[1]);
4501 (define_expand "neon_vreinterpretv4si<mode>"
4502 [(match_operand:V4SI 0 "s_register_operand" "")
4503 (match_operand:VQX 1 "s_register_operand" "")]
4506 neon_reinterpret (operands[0], operands[1]);
4510 (define_expand "neon_vreinterpretv4sf<mode>"
4511 [(match_operand:V4SF 0 "s_register_operand" "")
4512 (match_operand:VQX 1 "s_register_operand" "")]
4515 neon_reinterpret (operands[0], operands[1]);
4519 (define_expand "neon_vreinterpretv2di<mode>"
4520 [(match_operand:V2DI 0 "s_register_operand" "")
4521 (match_operand:VQX 1 "s_register_operand" "")]
4524 neon_reinterpret (operands[0], operands[1]);
4528 (define_expand "vec_load_lanes<mode><mode>"
4529 [(set (match_operand:VDQX 0 "s_register_operand")
4530 (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_operand")]
4534 (define_insn "neon_vld1<mode>"
4535 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
4536 (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_operand" "Um")]
4539 "vld1.<V_sz_elem>\t%h0, %A1"
4540 [(set_attr "neon_type" "neon_vld1_1_2_regs")]
4543 (define_insn "neon_vld1_lane<mode>"
4544 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4545 (unspec:VDX [(match_operand:<V_elem> 1 "neon_struct_operand" "Um")
4546 (match_operand:VDX 2 "s_register_operand" "0")
4547 (match_operand:SI 3 "immediate_operand" "i")]
4551 HOST_WIDE_INT lane = INTVAL (operands[3]);
4552 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4553 if (lane < 0 || lane >= max)
4554 error ("lane out of range");
4556 return "vld1.<V_sz_elem>\t%P0, %A1";
4558 return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1";
4560 [(set (attr "neon_type")
4561 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4562 (const_string "neon_vld1_1_2_regs")
4563 (const_string "neon_vld1_vld2_lane")))]
4566 (define_insn "neon_vld1_lane<mode>"
4567 [(set (match_operand:VQX 0 "s_register_operand" "=w")
4568 (unspec:VQX [(match_operand:<V_elem> 1 "neon_struct_operand" "Um")
4569 (match_operand:VQX 2 "s_register_operand" "0")
4570 (match_operand:SI 3 "immediate_operand" "i")]
4574 HOST_WIDE_INT lane = INTVAL (operands[3]);
4575 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4576 int regno = REGNO (operands[0]);
4577 if (lane < 0 || lane >= max)
4578 error ("lane out of range");
4579 else if (lane >= max / 2)
4583 operands[3] = GEN_INT (lane);
4585 operands[0] = gen_rtx_REG (<V_HALF>mode, regno);
4587 return "vld1.<V_sz_elem>\t%P0, %A1";
4589 return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1";
4591 [(set (attr "neon_type")
4592 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4593 (const_string "neon_vld1_1_2_regs")
4594 (const_string "neon_vld1_vld2_lane")))]
4597 (define_insn "neon_vld1_dup<mode>"
4598 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4599 (vec_duplicate:VDX (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
4602 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4603 return "vld1.<V_sz_elem>\t{%P0[]}, %A1";
4605 return "vld1.<V_sz_elem>\t%h0, %A1";
4607 [(set (attr "neon_type")
4608 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4609 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4610 (const_string "neon_vld1_1_2_regs")))]
4613 (define_insn "neon_vld1_dup<mode>"
4614 [(set (match_operand:VQ 0 "s_register_operand" "=w")
4615 (vec_duplicate:VQ (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
4618 return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, %A1";
4620 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
4623 (define_insn_and_split "neon_vld1_dupv2di"
4624 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
4625 (vec_duplicate:V2DI (match_operand:DI 1 "neon_struct_operand" "Um")))]
4628 "&& reload_completed"
4631 rtx tmprtx = gen_lowpart (DImode, operands[0]);
4632 emit_insn (gen_neon_vld1_dupdi (tmprtx, operands[1]));
4633 emit_move_insn (gen_highpart (DImode, operands[0]), tmprtx );
4636 [(set_attr "length" "8")
4637 (set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
4640 (define_expand "vec_store_lanes<mode><mode>"
4641 [(set (match_operand:VDQX 0 "neon_struct_operand")
4642 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand")]
4646 (define_insn "neon_vst1<mode>"
4647 [(set (match_operand:VDQX 0 "neon_struct_operand" "=Um")
4648 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")]
4651 "vst1.<V_sz_elem>\t%h1, %A0"
4652 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
4654 (define_insn "neon_vst1_lane<mode>"
4655 [(set (match_operand:<V_elem> 0 "neon_struct_operand" "=Um")
4657 [(match_operand:VDX 1 "s_register_operand" "w")
4658 (match_operand:SI 2 "immediate_operand" "i")]
4662 HOST_WIDE_INT lane = INTVAL (operands[2]);
4663 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4664 if (lane < 0 || lane >= max)
4665 error ("lane out of range");
4667 return "vst1.<V_sz_elem>\t{%P1}, %A0";
4669 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
4671 [(set (attr "neon_type")
4672 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 1))
4673 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4674 (const_string "neon_vst1_vst2_lane")))])
4676 (define_insn "neon_vst1_lane<mode>"
4677 [(set (match_operand:<V_elem> 0 "neon_struct_operand" "=Um")
4679 [(match_operand:VQX 1 "s_register_operand" "w")
4680 (match_operand:SI 2 "immediate_operand" "i")]
4684 HOST_WIDE_INT lane = INTVAL (operands[2]);
4685 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4686 int regno = REGNO (operands[1]);
4687 if (lane < 0 || lane >= max)
4688 error ("lane out of range");
4689 else if (lane >= max / 2)
4693 operands[2] = GEN_INT (lane);
4695 operands[1] = gen_rtx_REG (<V_HALF>mode, regno);
4697 return "vst1.<V_sz_elem>\t{%P1}, %A0";
4699 return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
4701 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4704 (define_expand "vec_load_lanesti<mode>"
4705 [(set (match_operand:TI 0 "s_register_operand")
4706 (unspec:TI [(match_operand:TI 1 "neon_struct_operand")
4707 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4711 (define_insn "neon_vld2<mode>"
4712 [(set (match_operand:TI 0 "s_register_operand" "=w")
4713 (unspec:TI [(match_operand:TI 1 "neon_struct_operand" "Um")
4714 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4718 if (<V_sz_elem> == 64)
4719 return "vld1.64\t%h0, %A1";
4721 return "vld2.<V_sz_elem>\t%h0, %A1";
4723 [(set (attr "neon_type")
4724 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4725 (const_string "neon_vld1_1_2_regs")
4726 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))]
4729 (define_expand "vec_load_lanesoi<mode>"
4730 [(set (match_operand:OI 0 "s_register_operand")
4731 (unspec:OI [(match_operand:OI 1 "neon_struct_operand")
4732 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4736 (define_insn "neon_vld2<mode>"
4737 [(set (match_operand:OI 0 "s_register_operand" "=w")
4738 (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um")
4739 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4742 "vld2.<V_sz_elem>\t%h0, %A1"
4743 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")])
4745 (define_insn "neon_vld2_lane<mode>"
4746 [(set (match_operand:TI 0 "s_register_operand" "=w")
4747 (unspec:TI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4748 (match_operand:TI 2 "s_register_operand" "0")
4749 (match_operand:SI 3 "immediate_operand" "i")
4750 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4754 HOST_WIDE_INT lane = INTVAL (operands[3]);
4755 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4756 int regno = REGNO (operands[0]);
4758 if (lane < 0 || lane >= max)
4759 error ("lane out of range");
4760 ops[0] = gen_rtx_REG (DImode, regno);
4761 ops[1] = gen_rtx_REG (DImode, regno + 2);
4762 ops[2] = operands[1];
4763 ops[3] = operands[3];
4764 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops);
4767 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4770 (define_insn "neon_vld2_lane<mode>"
4771 [(set (match_operand:OI 0 "s_register_operand" "=w")
4772 (unspec:OI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4773 (match_operand:OI 2 "s_register_operand" "0")
4774 (match_operand:SI 3 "immediate_operand" "i")
4775 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4779 HOST_WIDE_INT lane = INTVAL (operands[3]);
4780 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4781 int regno = REGNO (operands[0]);
4783 if (lane < 0 || lane >= max)
4784 error ("lane out of range");
4785 else if (lane >= max / 2)
4790 ops[0] = gen_rtx_REG (DImode, regno);
4791 ops[1] = gen_rtx_REG (DImode, regno + 4);
4792 ops[2] = operands[1];
4793 ops[3] = GEN_INT (lane);
4794 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops);
4797 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4800 (define_insn "neon_vld2_dup<mode>"
4801 [(set (match_operand:TI 0 "s_register_operand" "=w")
4802 (unspec:TI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4803 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4807 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4808 return "vld2.<V_sz_elem>\t{%e0[], %f0[]}, %A1";
4810 return "vld1.<V_sz_elem>\t%h0, %A1";
4812 [(set (attr "neon_type")
4813 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4814 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4815 (const_string "neon_vld1_1_2_regs")))]
4818 (define_expand "vec_store_lanesti<mode>"
4819 [(set (match_operand:TI 0 "neon_struct_operand")
4820 (unspec:TI [(match_operand:TI 1 "s_register_operand")
4821 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4825 (define_insn "neon_vst2<mode>"
4826 [(set (match_operand:TI 0 "neon_struct_operand" "=Um")
4827 (unspec:TI [(match_operand:TI 1 "s_register_operand" "w")
4828 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4832 if (<V_sz_elem> == 64)
4833 return "vst1.64\t%h1, %A0";
4835 return "vst2.<V_sz_elem>\t%h1, %A0";
4837 [(set (attr "neon_type")
4838 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4839 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4840 (const_string "neon_vst1_1_2_regs_vst2_2_regs")))]
4843 (define_expand "vec_store_lanesoi<mode>"
4844 [(set (match_operand:OI 0 "neon_struct_operand")
4845 (unspec:OI [(match_operand:OI 1 "s_register_operand")
4846 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4850 (define_insn "neon_vst2<mode>"
4851 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
4852 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4853 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4856 "vst2.<V_sz_elem>\t%h1, %A0"
4857 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]
4860 (define_insn "neon_vst2_lane<mode>"
4861 [(set (match_operand:<V_two_elem> 0 "neon_struct_operand" "=Um")
4862 (unspec:<V_two_elem>
4863 [(match_operand:TI 1 "s_register_operand" "w")
4864 (match_operand:SI 2 "immediate_operand" "i")
4865 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4869 HOST_WIDE_INT lane = INTVAL (operands[2]);
4870 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4871 int regno = REGNO (operands[1]);
4873 if (lane < 0 || lane >= max)
4874 error ("lane out of range");
4875 ops[0] = operands[0];
4876 ops[1] = gen_rtx_REG (DImode, regno);
4877 ops[2] = gen_rtx_REG (DImode, regno + 2);
4878 ops[3] = operands[2];
4879 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops);
4882 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4885 (define_insn "neon_vst2_lane<mode>"
4886 [(set (match_operand:<V_two_elem> 0 "neon_struct_operand" "=Um")
4887 (unspec:<V_two_elem>
4888 [(match_operand:OI 1 "s_register_operand" "w")
4889 (match_operand:SI 2 "immediate_operand" "i")
4890 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4894 HOST_WIDE_INT lane = INTVAL (operands[2]);
4895 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4896 int regno = REGNO (operands[1]);
4898 if (lane < 0 || lane >= max)
4899 error ("lane out of range");
4900 else if (lane >= max / 2)
4905 ops[0] = operands[0];
4906 ops[1] = gen_rtx_REG (DImode, regno);
4907 ops[2] = gen_rtx_REG (DImode, regno + 4);
4908 ops[3] = GEN_INT (lane);
4909 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops);
4912 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4915 (define_expand "vec_load_lanesei<mode>"
4916 [(set (match_operand:EI 0 "s_register_operand")
4917 (unspec:EI [(match_operand:EI 1 "neon_struct_operand")
4918 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4922 (define_insn "neon_vld3<mode>"
4923 [(set (match_operand:EI 0 "s_register_operand" "=w")
4924 (unspec:EI [(match_operand:EI 1 "neon_struct_operand" "Um")
4925 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4929 if (<V_sz_elem> == 64)
4930 return "vld1.64\t%h0, %A1";
4932 return "vld3.<V_sz_elem>\t%h0, %A1";
4934 [(set (attr "neon_type")
4935 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4936 (const_string "neon_vld1_1_2_regs")
4937 (const_string "neon_vld3_vld4")))]
4940 (define_expand "vec_load_lanesci<mode>"
4941 [(match_operand:CI 0 "s_register_operand")
4942 (match_operand:CI 1 "neon_struct_operand")
4943 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4946 emit_insn (gen_neon_vld3<mode> (operands[0], operands[1]));
4950 (define_expand "neon_vld3<mode>"
4951 [(match_operand:CI 0 "s_register_operand")
4952 (match_operand:CI 1 "neon_struct_operand")
4953 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4958 mem = adjust_address (operands[1], EImode, 0);
4959 emit_insn (gen_neon_vld3qa<mode> (operands[0], mem));
4960 mem = adjust_address (mem, EImode, GET_MODE_SIZE (EImode));
4961 emit_insn (gen_neon_vld3qb<mode> (operands[0], mem, operands[0]));
4965 (define_insn "neon_vld3qa<mode>"
4966 [(set (match_operand:CI 0 "s_register_operand" "=w")
4967 (unspec:CI [(match_operand:EI 1 "neon_struct_operand" "Um")
4968 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4972 int regno = REGNO (operands[0]);
4974 ops[0] = gen_rtx_REG (DImode, regno);
4975 ops[1] = gen_rtx_REG (DImode, regno + 4);
4976 ops[2] = gen_rtx_REG (DImode, regno + 8);
4977 ops[3] = operands[1];
4978 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops);
4981 [(set_attr "neon_type" "neon_vld3_vld4")]
4984 (define_insn "neon_vld3qb<mode>"
4985 [(set (match_operand:CI 0 "s_register_operand" "=w")
4986 (unspec:CI [(match_operand:EI 1 "neon_struct_operand" "Um")
4987 (match_operand:CI 2 "s_register_operand" "0")
4988 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4992 int regno = REGNO (operands[0]);
4994 ops[0] = gen_rtx_REG (DImode, regno + 2);
4995 ops[1] = gen_rtx_REG (DImode, regno + 6);
4996 ops[2] = gen_rtx_REG (DImode, regno + 10);
4997 ops[3] = operands[1];
4998 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops);
5001 [(set_attr "neon_type" "neon_vld3_vld4")]
5004 (define_insn "neon_vld3_lane<mode>"
5005 [(set (match_operand:EI 0 "s_register_operand" "=w")
5006 (unspec:EI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5007 (match_operand:EI 2 "s_register_operand" "0")
5008 (match_operand:SI 3 "immediate_operand" "i")
5009 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5013 HOST_WIDE_INT lane = INTVAL (operands[3]);
5014 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5015 int regno = REGNO (operands[0]);
5017 if (lane < 0 || lane >= max)
5018 error ("lane out of range");
5019 ops[0] = gen_rtx_REG (DImode, regno);
5020 ops[1] = gen_rtx_REG (DImode, regno + 2);
5021 ops[2] = gen_rtx_REG (DImode, regno + 4);
5022 ops[3] = operands[1];
5023 ops[4] = operands[3];
5024 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, %3",
5028 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5031 (define_insn "neon_vld3_lane<mode>"
5032 [(set (match_operand:CI 0 "s_register_operand" "=w")
5033 (unspec:CI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5034 (match_operand:CI 2 "s_register_operand" "0")
5035 (match_operand:SI 3 "immediate_operand" "i")
5036 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5040 HOST_WIDE_INT lane = INTVAL (operands[3]);
5041 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5042 int regno = REGNO (operands[0]);
5044 if (lane < 0 || lane >= max)
5045 error ("lane out of range");
5046 else if (lane >= max / 2)
5051 ops[0] = gen_rtx_REG (DImode, regno);
5052 ops[1] = gen_rtx_REG (DImode, regno + 4);
5053 ops[2] = gen_rtx_REG (DImode, regno + 8);
5054 ops[3] = operands[1];
5055 ops[4] = GEN_INT (lane);
5056 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, %3",
5060 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5063 (define_insn "neon_vld3_dup<mode>"
5064 [(set (match_operand:EI 0 "s_register_operand" "=w")
5065 (unspec:EI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5066 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5070 if (GET_MODE_NUNITS (<MODE>mode) > 1)
5072 int regno = REGNO (operands[0]);
5074 ops[0] = gen_rtx_REG (DImode, regno);
5075 ops[1] = gen_rtx_REG (DImode, regno + 2);
5076 ops[2] = gen_rtx_REG (DImode, regno + 4);
5077 ops[3] = operands[1];
5078 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[], %P1[], %P2[]}, %3", ops);
5082 return "vld1.<V_sz_elem>\t%h0, %A1";
5084 [(set (attr "neon_type")
5085 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
5086 (const_string "neon_vld3_vld4_all_lanes")
5087 (const_string "neon_vld1_1_2_regs")))])
5089 (define_expand "vec_store_lanesei<mode>"
5090 [(set (match_operand:EI 0 "neon_struct_operand")
5091 (unspec:EI [(match_operand:EI 1 "s_register_operand")
5092 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5096 (define_insn "neon_vst3<mode>"
5097 [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5098 (unspec:EI [(match_operand:EI 1 "s_register_operand" "w")
5099 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5103 if (<V_sz_elem> == 64)
5104 return "vst1.64\t%h1, %A0";
5106 return "vst3.<V_sz_elem>\t%h1, %A0";
5108 [(set (attr "neon_type")
5109 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5110 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
5111 (const_string "neon_vst2_4_regs_vst3_vst4")))])
5113 (define_expand "vec_store_lanesci<mode>"
5114 [(match_operand:CI 0 "neon_struct_operand")
5115 (match_operand:CI 1 "s_register_operand")
5116 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5119 emit_insn (gen_neon_vst3<mode> (operands[0], operands[1]));
5123 (define_expand "neon_vst3<mode>"
5124 [(match_operand:CI 0 "neon_struct_operand")
5125 (match_operand:CI 1 "s_register_operand")
5126 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5131 mem = adjust_address (operands[0], EImode, 0);
5132 emit_insn (gen_neon_vst3qa<mode> (mem, operands[1]));
5133 mem = adjust_address (mem, EImode, GET_MODE_SIZE (EImode));
5134 emit_insn (gen_neon_vst3qb<mode> (mem, operands[1]));
5138 (define_insn "neon_vst3qa<mode>"
5139 [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5140 (unspec:EI [(match_operand:CI 1 "s_register_operand" "w")
5141 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5145 int regno = REGNO (operands[1]);
5147 ops[0] = operands[0];
5148 ops[1] = gen_rtx_REG (DImode, regno);
5149 ops[2] = gen_rtx_REG (DImode, regno + 4);
5150 ops[3] = gen_rtx_REG (DImode, regno + 8);
5151 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops);
5154 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5157 (define_insn "neon_vst3qb<mode>"
5158 [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5159 (unspec:EI [(match_operand:CI 1 "s_register_operand" "w")
5160 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5164 int regno = REGNO (operands[1]);
5166 ops[0] = operands[0];
5167 ops[1] = gen_rtx_REG (DImode, regno + 2);
5168 ops[2] = gen_rtx_REG (DImode, regno + 6);
5169 ops[3] = gen_rtx_REG (DImode, regno + 10);
5170 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops);
5173 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5176 (define_insn "neon_vst3_lane<mode>"
5177 [(set (match_operand:<V_three_elem> 0 "neon_struct_operand" "=Um")
5178 (unspec:<V_three_elem>
5179 [(match_operand:EI 1 "s_register_operand" "w")
5180 (match_operand:SI 2 "immediate_operand" "i")
5181 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5185 HOST_WIDE_INT lane = INTVAL (operands[2]);
5186 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5187 int regno = REGNO (operands[1]);
5189 if (lane < 0 || lane >= max)
5190 error ("lane out of range");
5191 ops[0] = operands[0];
5192 ops[1] = gen_rtx_REG (DImode, regno);
5193 ops[2] = gen_rtx_REG (DImode, regno + 2);
5194 ops[3] = gen_rtx_REG (DImode, regno + 4);
5195 ops[4] = operands[2];
5196 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, %0",
5200 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5203 (define_insn "neon_vst3_lane<mode>"
5204 [(set (match_operand:<V_three_elem> 0 "neon_struct_operand" "=Um")
5205 (unspec:<V_three_elem>
5206 [(match_operand:CI 1 "s_register_operand" "w")
5207 (match_operand:SI 2 "immediate_operand" "i")
5208 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5212 HOST_WIDE_INT lane = INTVAL (operands[2]);
5213 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5214 int regno = REGNO (operands[1]);
5216 if (lane < 0 || lane >= max)
5217 error ("lane out of range");
5218 else if (lane >= max / 2)
5223 ops[0] = operands[0];
5224 ops[1] = gen_rtx_REG (DImode, regno);
5225 ops[2] = gen_rtx_REG (DImode, regno + 4);
5226 ops[3] = gen_rtx_REG (DImode, regno + 8);
5227 ops[4] = GEN_INT (lane);
5228 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, %0",
5232 [(set_attr "neon_type" "neon_vst3_vst4_lane")])
5234 (define_expand "vec_load_lanesoi<mode>"
5235 [(set (match_operand:OI 0 "s_register_operand")
5236 (unspec:OI [(match_operand:OI 1 "neon_struct_operand")
5237 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5241 (define_insn "neon_vld4<mode>"
5242 [(set (match_operand:OI 0 "s_register_operand" "=w")
5243 (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um")
5244 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5248 if (<V_sz_elem> == 64)
5249 return "vld1.64\t%h0, %A1";
5251 return "vld4.<V_sz_elem>\t%h0, %A1";
5253 [(set (attr "neon_type")
5254 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5255 (const_string "neon_vld1_1_2_regs")
5256 (const_string "neon_vld3_vld4")))]
5259 (define_expand "vec_load_lanesxi<mode>"
5260 [(match_operand:XI 0 "s_register_operand")
5261 (match_operand:XI 1 "neon_struct_operand")
5262 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5265 emit_insn (gen_neon_vld4<mode> (operands[0], operands[1]));
5269 (define_expand "neon_vld4<mode>"
5270 [(match_operand:XI 0 "s_register_operand")
5271 (match_operand:XI 1 "neon_struct_operand")
5272 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5277 mem = adjust_address (operands[1], OImode, 0);
5278 emit_insn (gen_neon_vld4qa<mode> (operands[0], mem));
5279 mem = adjust_address (mem, OImode, GET_MODE_SIZE (OImode));
5280 emit_insn (gen_neon_vld4qb<mode> (operands[0], mem, operands[0]));
5284 (define_insn "neon_vld4qa<mode>"
5285 [(set (match_operand:XI 0 "s_register_operand" "=w")
5286 (unspec:XI [(match_operand:OI 1 "neon_struct_operand" "Um")
5287 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5291 int regno = REGNO (operands[0]);
5293 ops[0] = gen_rtx_REG (DImode, regno);
5294 ops[1] = gen_rtx_REG (DImode, regno + 4);
5295 ops[2] = gen_rtx_REG (DImode, regno + 8);
5296 ops[3] = gen_rtx_REG (DImode, regno + 12);
5297 ops[4] = operands[1];
5298 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops);
5301 [(set_attr "neon_type" "neon_vld3_vld4")]
5304 (define_insn "neon_vld4qb<mode>"
5305 [(set (match_operand:XI 0 "s_register_operand" "=w")
5306 (unspec:XI [(match_operand:OI 1 "neon_struct_operand" "Um")
5307 (match_operand:XI 2 "s_register_operand" "0")
5308 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5312 int regno = REGNO (operands[0]);
5314 ops[0] = gen_rtx_REG (DImode, regno + 2);
5315 ops[1] = gen_rtx_REG (DImode, regno + 6);
5316 ops[2] = gen_rtx_REG (DImode, regno + 10);
5317 ops[3] = gen_rtx_REG (DImode, regno + 14);
5318 ops[4] = operands[1];
5319 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops);
5322 [(set_attr "neon_type" "neon_vld3_vld4")]
5325 (define_insn "neon_vld4_lane<mode>"
5326 [(set (match_operand:OI 0 "s_register_operand" "=w")
5327 (unspec:OI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5328 (match_operand:OI 2 "s_register_operand" "0")
5329 (match_operand:SI 3 "immediate_operand" "i")
5330 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5334 HOST_WIDE_INT lane = INTVAL (operands[3]);
5335 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5336 int regno = REGNO (operands[0]);
5338 if (lane < 0 || lane >= max)
5339 error ("lane out of range");
5340 ops[0] = gen_rtx_REG (DImode, regno);
5341 ops[1] = gen_rtx_REG (DImode, regno + 2);
5342 ops[2] = gen_rtx_REG (DImode, regno + 4);
5343 ops[3] = gen_rtx_REG (DImode, regno + 6);
5344 ops[4] = operands[1];
5345 ops[5] = operands[3];
5346 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, %A4",
5350 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5353 (define_insn "neon_vld4_lane<mode>"
5354 [(set (match_operand:XI 0 "s_register_operand" "=w")
5355 (unspec:XI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5356 (match_operand:XI 2 "s_register_operand" "0")
5357 (match_operand:SI 3 "immediate_operand" "i")
5358 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5362 HOST_WIDE_INT lane = INTVAL (operands[3]);
5363 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5364 int regno = REGNO (operands[0]);
5366 if (lane < 0 || lane >= max)
5367 error ("lane out of range");
5368 else if (lane >= max / 2)
5373 ops[0] = gen_rtx_REG (DImode, regno);
5374 ops[1] = gen_rtx_REG (DImode, regno + 4);
5375 ops[2] = gen_rtx_REG (DImode, regno + 8);
5376 ops[3] = gen_rtx_REG (DImode, regno + 12);
5377 ops[4] = operands[1];
5378 ops[5] = GEN_INT (lane);
5379 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, %A4",
5383 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5386 (define_insn "neon_vld4_dup<mode>"
5387 [(set (match_operand:OI 0 "s_register_operand" "=w")
5388 (unspec:OI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5389 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5393 if (GET_MODE_NUNITS (<MODE>mode) > 1)
5395 int regno = REGNO (operands[0]);
5397 ops[0] = gen_rtx_REG (DImode, regno);
5398 ops[1] = gen_rtx_REG (DImode, regno + 2);
5399 ops[2] = gen_rtx_REG (DImode, regno + 4);
5400 ops[3] = gen_rtx_REG (DImode, regno + 6);
5401 ops[4] = operands[1];
5402 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[], %P1[], %P2[], %P3[]}, %A4",
5407 return "vld1.<V_sz_elem>\t%h0, %A1";
5409 [(set (attr "neon_type")
5410 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
5411 (const_string "neon_vld3_vld4_all_lanes")
5412 (const_string "neon_vld1_1_2_regs")))]
5415 (define_expand "vec_store_lanesoi<mode>"
5416 [(set (match_operand:OI 0 "neon_struct_operand")
5417 (unspec:OI [(match_operand:OI 1 "s_register_operand")
5418 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5422 (define_insn "neon_vst4<mode>"
5423 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5424 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
5425 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5429 if (<V_sz_elem> == 64)
5430 return "vst1.64\t%h1, %A0";
5432 return "vst4.<V_sz_elem>\t%h1, %A0";
5434 [(set (attr "neon_type")
5435 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5436 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
5437 (const_string "neon_vst2_4_regs_vst3_vst4")))]
5440 (define_expand "vec_store_lanesxi<mode>"
5441 [(match_operand:XI 0 "neon_struct_operand")
5442 (match_operand:XI 1 "s_register_operand")
5443 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5446 emit_insn (gen_neon_vst4<mode> (operands[0], operands[1]));
5450 (define_expand "neon_vst4<mode>"
5451 [(match_operand:XI 0 "neon_struct_operand")
5452 (match_operand:XI 1 "s_register_operand")
5453 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5458 mem = adjust_address (operands[0], OImode, 0);
5459 emit_insn (gen_neon_vst4qa<mode> (mem, operands[1]));
5460 mem = adjust_address (mem, OImode, GET_MODE_SIZE (OImode));
5461 emit_insn (gen_neon_vst4qb<mode> (mem, operands[1]));
5465 (define_insn "neon_vst4qa<mode>"
5466 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5467 (unspec:OI [(match_operand:XI 1 "s_register_operand" "w")
5468 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5472 int regno = REGNO (operands[1]);
5474 ops[0] = operands[0];
5475 ops[1] = gen_rtx_REG (DImode, regno);
5476 ops[2] = gen_rtx_REG (DImode, regno + 4);
5477 ops[3] = gen_rtx_REG (DImode, regno + 8);
5478 ops[4] = gen_rtx_REG (DImode, regno + 12);
5479 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops);
5482 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5485 (define_insn "neon_vst4qb<mode>"
5486 [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5487 (unspec:OI [(match_operand:XI 1 "s_register_operand" "w")
5488 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5492 int regno = REGNO (operands[1]);
5494 ops[0] = operands[0];
5495 ops[1] = gen_rtx_REG (DImode, regno + 2);
5496 ops[2] = gen_rtx_REG (DImode, regno + 6);
5497 ops[3] = gen_rtx_REG (DImode, regno + 10);
5498 ops[4] = gen_rtx_REG (DImode, regno + 14);
5499 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops);
5502 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5505 (define_insn "neon_vst4_lane<mode>"
5506 [(set (match_operand:<V_four_elem> 0 "neon_struct_operand" "=Um")
5507 (unspec:<V_four_elem>
5508 [(match_operand:OI 1 "s_register_operand" "w")
5509 (match_operand:SI 2 "immediate_operand" "i")
5510 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5514 HOST_WIDE_INT lane = INTVAL (operands[2]);
5515 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5516 int regno = REGNO (operands[1]);
5518 if (lane < 0 || lane >= max)
5519 error ("lane out of range");
5520 ops[0] = operands[0];
5521 ops[1] = gen_rtx_REG (DImode, regno);
5522 ops[2] = gen_rtx_REG (DImode, regno + 2);
5523 ops[3] = gen_rtx_REG (DImode, regno + 4);
5524 ops[4] = gen_rtx_REG (DImode, regno + 6);
5525 ops[5] = operands[2];
5526 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, %A0",
5530 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5533 (define_insn "neon_vst4_lane<mode>"
5534 [(set (match_operand:<V_four_elem> 0 "neon_struct_operand" "=Um")
5535 (unspec:<V_four_elem>
5536 [(match_operand:XI 1 "s_register_operand" "w")
5537 (match_operand:SI 2 "immediate_operand" "i")
5538 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5542 HOST_WIDE_INT lane = INTVAL (operands[2]);
5543 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5544 int regno = REGNO (operands[1]);
5546 if (lane < 0 || lane >= max)
5547 error ("lane out of range");
5548 else if (lane >= max / 2)
5553 ops[0] = operands[0];
5554 ops[1] = gen_rtx_REG (DImode, regno);
5555 ops[2] = gen_rtx_REG (DImode, regno + 4);
5556 ops[3] = gen_rtx_REG (DImode, regno + 8);
5557 ops[4] = gen_rtx_REG (DImode, regno + 12);
5558 ops[5] = GEN_INT (lane);
5559 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, %A0",
5563 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5566 (define_expand "neon_vand<mode>"
5567 [(match_operand:VDQX 0 "s_register_operand" "")
5568 (match_operand:VDQX 1 "s_register_operand" "")
5569 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5570 (match_operand:SI 3 "immediate_operand" "")]
5573 emit_insn (gen_and<mode>3 (operands[0], operands[1], operands[2]));
5577 (define_expand "neon_vorr<mode>"
5578 [(match_operand:VDQX 0 "s_register_operand" "")
5579 (match_operand:VDQX 1 "s_register_operand" "")
5580 (match_operand:VDQX 2 "neon_logic_op2" "")
5581 (match_operand:SI 3 "immediate_operand" "")]
5584 emit_insn (gen_ior<mode>3 (operands[0], operands[1], operands[2]));
5588 (define_expand "neon_veor<mode>"
5589 [(match_operand:VDQX 0 "s_register_operand" "")
5590 (match_operand:VDQX 1 "s_register_operand" "")
5591 (match_operand:VDQX 2 "s_register_operand" "")
5592 (match_operand:SI 3 "immediate_operand" "")]
5595 emit_insn (gen_xor<mode>3 (operands[0], operands[1], operands[2]));
5599 (define_expand "neon_vbic<mode>"
5600 [(match_operand:VDQX 0 "s_register_operand" "")
5601 (match_operand:VDQX 1 "s_register_operand" "")
5602 (match_operand:VDQX 2 "neon_logic_op2" "")
5603 (match_operand:SI 3 "immediate_operand" "")]
5606 emit_insn (gen_bic<mode>3_neon (operands[0], operands[1], operands[2]));
5610 (define_expand "neon_vorn<mode>"
5611 [(match_operand:VDQX 0 "s_register_operand" "")
5612 (match_operand:VDQX 1 "s_register_operand" "")
5613 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5614 (match_operand:SI 3 "immediate_operand" "")]
5617 emit_insn (gen_orn<mode>3_neon (operands[0], operands[1], operands[2]));
5621 (define_insn "neon_vec_unpack<US>_lo_<mode>"
5622 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5623 (SE:<V_unpack> (vec_select:<V_HALF>
5624 (match_operand:VU 1 "register_operand" "w")
5625 (match_operand:VU 2 "vect_par_constant_low" ""))))]
5626 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5627 "vmovl.<US><V_sz_elem> %q0, %e1"
5628 [(set_attr "neon_type" "neon_shift_1")]
5631 (define_insn "neon_vec_unpack<US>_hi_<mode>"
5632 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5633 (SE:<V_unpack> (vec_select:<V_HALF>
5634 (match_operand:VU 1 "register_operand" "w")
5635 (match_operand:VU 2 "vect_par_constant_high" ""))))]
5636 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5637 "vmovl.<US><V_sz_elem> %q0, %f1"
5638 [(set_attr "neon_type" "neon_shift_1")]
5641 (define_expand "vec_unpack<US>_hi_<mode>"
5642 [(match_operand:<V_unpack> 0 "register_operand" "")
5643 (SE:<V_unpack> (match_operand:VU 1 "register_operand"))]
5644 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5646 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5649 for (i = 0; i < (<V_mode_nunits>/2); i++)
5650 RTVEC_ELT (v, i) = GEN_INT ((<V_mode_nunits>/2) + i);
5652 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5653 emit_insn (gen_neon_vec_unpack<US>_hi_<mode> (operands[0],
5660 (define_expand "vec_unpack<US>_lo_<mode>"
5661 [(match_operand:<V_unpack> 0 "register_operand" "")
5662 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))]
5663 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5665 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5668 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5669 RTVEC_ELT (v, i) = GEN_INT (i);
5670 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5671 emit_insn (gen_neon_vec_unpack<US>_lo_<mode> (operands[0],
5678 (define_insn "neon_vec_<US>mult_lo_<mode>"
5679 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5680 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5681 (match_operand:VU 1 "register_operand" "w")
5682 (match_operand:VU 2 "vect_par_constant_low" "")))
5683 (SE:<V_unpack> (vec_select:<V_HALF>
5684 (match_operand:VU 3 "register_operand" "w")
5686 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5687 "vmull.<US><V_sz_elem> %q0, %e1, %e3"
5688 [(set_attr "neon_type" "neon_shift_1")]
5691 (define_expand "vec_widen_<US>mult_lo_<mode>"
5692 [(match_operand:<V_unpack> 0 "register_operand" "")
5693 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5694 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5695 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5697 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5700 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5701 RTVEC_ELT (v, i) = GEN_INT (i);
5702 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5704 emit_insn (gen_neon_vec_<US>mult_lo_<mode> (operands[0],
5712 (define_insn "neon_vec_<US>mult_hi_<mode>"
5713 [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5714 (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5715 (match_operand:VU 1 "register_operand" "w")
5716 (match_operand:VU 2 "vect_par_constant_high" "")))
5717 (SE:<V_unpack> (vec_select:<V_HALF>
5718 (match_operand:VU 3 "register_operand" "w")
5720 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5721 "vmull.<US><V_sz_elem> %q0, %f1, %f3"
5722 [(set_attr "neon_type" "neon_shift_1")]
5725 (define_expand "vec_widen_<US>mult_hi_<mode>"
5726 [(match_operand:<V_unpack> 0 "register_operand" "")
5727 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5728 (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5729 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5731 rtvec v = rtvec_alloc (<V_mode_nunits>/2) ;
5734 for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5735 RTVEC_ELT (v, i) = GEN_INT (<V_mode_nunits>/2 + i);
5736 t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5738 emit_insn (gen_neon_vec_<US>mult_hi_<mode> (operands[0],
5747 (define_insn "neon_vec_<US>shiftl_<mode>"
5748 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5749 (SE:<V_widen> (ashift:VW (match_operand:VW 1 "register_operand" "w")
5750 (match_operand:<V_innermode> 2 "const_neon_scalar_shift_amount_operand" ""))))]
5753 return "vshll.<US><V_sz_elem> %q0, %P1, %2";
5755 [(set_attr "neon_type" "neon_shift_1")]
5758 (define_expand "vec_widen_<US>shiftl_lo_<mode>"
5759 [(match_operand:<V_unpack> 0 "register_operand" "")
5760 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5761 (match_operand:SI 2 "immediate_operand" "i")]
5762 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5764 emit_insn (gen_neon_vec_<US>shiftl_<V_half> (operands[0],
5765 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode, 0),
5771 (define_expand "vec_widen_<US>shiftl_hi_<mode>"
5772 [(match_operand:<V_unpack> 0 "register_operand" "")
5773 (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5774 (match_operand:SI 2 "immediate_operand" "i")]
5775 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5777 emit_insn (gen_neon_vec_<US>shiftl_<V_half> (operands[0],
5778 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode,
5779 GET_MODE_SIZE (<V_HALF>mode)),
5785 ;; Vectorize for non-neon-quad case
5786 (define_insn "neon_unpack<US>_<mode>"
5787 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5788 (SE:<V_widen> (match_operand:VDI 1 "register_operand" "w")))]
5790 "vmovl.<US><V_sz_elem> %q0, %P1"
5791 [(set_attr "neon_type" "neon_shift_1")]
5794 (define_expand "vec_unpack<US>_lo_<mode>"
5795 [(match_operand:<V_double_width> 0 "register_operand" "")
5796 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5799 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5800 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5801 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5807 (define_expand "vec_unpack<US>_hi_<mode>"
5808 [(match_operand:<V_double_width> 0 "register_operand" "")
5809 (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5812 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5813 emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5814 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5820 (define_insn "neon_vec_<US>mult_<mode>"
5821 [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5822 (mult:<V_widen> (SE:<V_widen>
5823 (match_operand:VDI 1 "register_operand" "w"))
5825 (match_operand:VDI 2 "register_operand" "w"))))]
5827 "vmull.<US><V_sz_elem> %q0, %P1, %P2"
5828 [(set_attr "neon_type" "neon_shift_1")]
5831 (define_expand "vec_widen_<US>mult_hi_<mode>"
5832 [(match_operand:<V_double_width> 0 "register_operand" "")
5833 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5834 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5837 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5838 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5839 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5846 (define_expand "vec_widen_<US>mult_lo_<mode>"
5847 [(match_operand:<V_double_width> 0 "register_operand" "")
5848 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5849 (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5852 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5853 emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5854 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5861 (define_expand "vec_widen_<US>shiftl_hi_<mode>"
5862 [(match_operand:<V_double_width> 0 "register_operand" "")
5863 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5864 (match_operand:SI 2 "immediate_operand" "i")]
5867 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5868 emit_insn (gen_neon_vec_<US>shiftl_<mode> (tmpreg, operands[1], operands[2]));
5869 emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5875 (define_expand "vec_widen_<US>shiftl_lo_<mode>"
5876 [(match_operand:<V_double_width> 0 "register_operand" "")
5877 (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5878 (match_operand:SI 2 "immediate_operand" "i")]
5881 rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5882 emit_insn (gen_neon_vec_<US>shiftl_<mode> (tmpreg, operands[1], operands[2]));
5883 emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5889 ; FIXME: These instruction patterns can't be used safely in big-endian mode
5890 ; because the ordering of vector elements in Q registers is different from what
5891 ; the semantics of the instructions require.
5893 (define_insn "vec_pack_trunc_<mode>"
5894 [(set (match_operand:<V_narrow_pack> 0 "register_operand" "=&w")
5895 (vec_concat:<V_narrow_pack>
5896 (truncate:<V_narrow>
5897 (match_operand:VN 1 "register_operand" "w"))
5898 (truncate:<V_narrow>
5899 (match_operand:VN 2 "register_operand" "w"))))]
5900 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5901 "vmovn.i<V_sz_elem>\t%e0, %q1\;vmovn.i<V_sz_elem>\t%f0, %q2"
5902 [(set_attr "neon_type" "neon_shift_1")
5903 (set_attr "length" "8")]
5906 ;; For the non-quad case.
5907 (define_insn "neon_vec_pack_trunc_<mode>"
5908 [(set (match_operand:<V_narrow> 0 "register_operand" "=w")
5909 (truncate:<V_narrow> (match_operand:VN 1 "register_operand" "w")))]
5910 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5911 "vmovn.i<V_sz_elem>\t%P0, %q1"
5912 [(set_attr "neon_type" "neon_shift_1")]
5915 (define_expand "vec_pack_trunc_<mode>"
5916 [(match_operand:<V_narrow_pack> 0 "register_operand" "")
5917 (match_operand:VSHFT 1 "register_operand" "")
5918 (match_operand:VSHFT 2 "register_operand")]
5919 "TARGET_NEON && !BYTES_BIG_ENDIAN"
5921 rtx tempreg = gen_reg_rtx (<V_DOUBLE>mode);
5923 emit_insn (gen_move_lo_quad_<V_double> (tempreg, operands[1]));
5924 emit_insn (gen_move_hi_quad_<V_double> (tempreg, operands[2]));
5925 emit_insn (gen_neon_vec_pack_trunc_<V_double> (operands[0], tempreg));
5929 (define_insn "neon_vabd<mode>_2"
5930 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
5931 (abs:VDQ (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
5932 (match_operand:VDQ 2 "s_register_operand" "w"))))]
5933 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
5934 "vabd.<V_s_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2"
5935 [(set (attr "neon_type")
5936 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
5937 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
5938 (const_string "neon_fp_vadd_ddd_vabs_dd")
5939 (const_string "neon_fp_vadd_qqq_vabs_qq"))
5940 (const_string "neon_int_5")))]
5943 (define_insn "neon_vabd<mode>_3"
5944 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
5945 (abs:VDQ (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
5946 (match_operand:VDQ 2 "s_register_operand" "w")]
5948 "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
5949 "vabd.<V_if_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2"
5950 [(set (attr "neon_type")
5951 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
5952 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
5953 (const_string "neon_fp_vadd_ddd_vabs_dd")
5954 (const_string "neon_fp_vadd_qqq_vabs_qq"))
5955 (const_string "neon_int_5")))]
5958 ;; Copy from core-to-neon regs, then extend, not vice-versa
5961 [(set (match_operand:DI 0 "s_register_operand" "")
5962 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
5963 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
5964 [(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1)))
5965 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 32)))]
5967 operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0]));
5971 [(set (match_operand:DI 0 "s_register_operand" "")
5972 (sign_extend:DI (match_operand:HI 1 "s_register_operand" "")))]
5973 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
5974 [(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1)))
5975 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
5977 operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0]));
5981 [(set (match_operand:DI 0 "s_register_operand" "")
5982 (sign_extend:DI (match_operand:QI 1 "s_register_operand" "")))]
5983 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
5984 [(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1)))
5985 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
5987 operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0]));
5991 [(set (match_operand:DI 0 "s_register_operand" "")
5992 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
5993 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
5994 [(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1)))
5995 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 32)))]
5997 operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0]));
6001 [(set (match_operand:DI 0 "s_register_operand" "")
6002 (zero_extend:DI (match_operand:HI 1 "s_register_operand" "")))]
6003 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6004 [(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1)))
6005 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
6007 operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0]));
6011 [(set (match_operand:DI 0 "s_register_operand" "")
6012 (zero_extend:DI (match_operand:QI 1 "s_register_operand" "")))]
6013 "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6014 [(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1)))
6015 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
6017 operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0]));