1 ;; ARM NEON coprocessor Machine Description
2 ;; Copyright (C) 2006, 2007 Free Software Foundation, Inc.
3 ;; Written by CodeSourcery.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; Constants for unspecs.
23 [(UNSPEC_ASHIFT_SIGNED 65)
24 (UNSPEC_ASHIFT_UNSIGNED 66)
59 (UNSPEC_VLD1_LANE 101)
62 (UNSPEC_VLD2_LANE 104)
67 (UNSPEC_VLD3_LANE 109)
72 (UNSPEC_VLD4_LANE 114)
77 (UNSPEC_VMLA_LANE 119)
78 (UNSPEC_VMLAL_LANE 120)
81 (UNSPEC_VMLS_LANE 123)
82 (UNSPEC_VMLSL_LANE 124)
87 (UNSPEC_VMUL_LANE 129)
88 (UNSPEC_VMULL_LANE 130)
105 (UNSPEC_VQDMLAL_LANE 147)
107 (UNSPEC_VQDMLSL_LANE 149)
109 (UNSPEC_VQDMULH_LANE 151)
111 (UNSPEC_VQDMULL_LANE 153)
117 (UNSPEC_VQSHLU_N 159)
118 (UNSPEC_VQSHRN_N 160)
119 (UNSPEC_VQSHRUN_N 161)
128 (UNSPEC_VSET_LANE 170)
138 (UNSPEC_VST1_LANE 180)
140 (UNSPEC_VST2_LANE 182)
144 (UNSPEC_VST3_LANE 186)
148 (UNSPEC_VST4_LANE 190)
149 (UNSPEC_VSTRUCTDUMMY 191)
164 ;; Double-width vector modes.
165 (define_mode_iterator VD [V8QI V4HI V2SI V2SF])
167 ;; Double-width vector modes plus 64-bit elements.
168 (define_mode_iterator VDX [V8QI V4HI V2SI V2SF DI])
170 ;; Same, without floating-point elements.
171 (define_mode_iterator VDI [V8QI V4HI V2SI])
173 ;; Quad-width vector modes.
174 (define_mode_iterator VQ [V16QI V8HI V4SI V4SF])
176 ;; Quad-width vector modes plus 64-bit elements.
177 (define_mode_iterator VQX [V16QI V8HI V4SI V4SF V2DI])
179 ;; Same, without floating-point elements.
180 (define_mode_iterator VQI [V16QI V8HI V4SI])
182 ;; Same, with TImode added, for moves.
183 (define_mode_iterator VQXMOV [V16QI V8HI V4SI V4SF V2DI TI])
185 ;; Opaque structure types wider than TImode.
186 (define_mode_iterator VSTRUCT [EI OI CI XI])
188 ;; Number of instructions needed to load/store struct elements. FIXME!
189 (define_mode_attr V_slen [(EI "2") (OI "2") (CI "3") (XI "4")])
191 ;; Opaque structure types used in table lookups (except vtbl1/vtbx1).
192 (define_mode_iterator VTAB [TI EI OI])
194 ;; vtbl<n> suffix for above modes.
195 (define_mode_attr VTAB_n [(TI "2") (EI "3") (OI "4")])
198 (define_mode_iterator VW [V8QI V4HI V2SI])
201 (define_mode_iterator VN [V8HI V4SI V2DI])
203 ;; All supported vector modes (except singleton DImode).
204 (define_mode_iterator VDQ [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF V2DI])
206 ;; All supported vector modes (except those with 64-bit integer elements).
207 (define_mode_iterator VDQW [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF])
209 ;; Supported integer vector modes (not 64 bit elements).
210 (define_mode_iterator VDQIW [V8QI V16QI V4HI V8HI V2SI V4SI])
212 ;; Supported integer vector modes (not singleton DI)
213 (define_mode_iterator VDQI [V8QI V16QI V4HI V8HI V2SI V4SI V2DI])
215 ;; Vector modes, including 64-bit integer elements.
216 (define_mode_iterator VDQX [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF DI V2DI])
218 ;; Vector modes including 64-bit integer elements, but no floats.
219 (define_mode_iterator VDQIX [V8QI V16QI V4HI V8HI V2SI V4SI DI V2DI])
221 ;; Vector modes for float->int conversions.
222 (define_mode_iterator VCVTF [V2SF V4SF])
224 ;; Vector modes form int->float conversions.
225 (define_mode_iterator VCVTI [V2SI V4SI])
227 ;; Vector modes for doubleword multiply-accumulate, etc. insns.
228 (define_mode_iterator VMD [V4HI V2SI V2SF])
230 ;; Vector modes for quadword multiply-accumulate, etc. insns.
231 (define_mode_iterator VMQ [V8HI V4SI V4SF])
233 ;; Above modes combined.
234 (define_mode_iterator VMDQ [V4HI V2SI V2SF V8HI V4SI V4SF])
236 ;; As VMD, but integer modes only.
237 (define_mode_iterator VMDI [V4HI V2SI])
239 ;; As VMQ, but integer modes only.
240 (define_mode_iterator VMQI [V8HI V4SI])
242 ;; Above modes combined.
243 (define_mode_iterator VMDQI [V4HI V2SI V8HI V4SI])
245 ;; Modes with 8-bit and 16-bit elements.
246 (define_mode_iterator VX [V8QI V4HI V16QI V8HI])
248 ;; Modes with 8-bit elements.
249 (define_mode_iterator VE [V8QI V16QI])
251 ;; Modes with 64-bit elements only.
252 (define_mode_iterator V64 [DI V2DI])
254 ;; Modes with 32-bit elements only.
255 (define_mode_iterator V32 [V2SI V2SF V4SI V4SF])
257 ;; (Opposite) mode to convert to/from for above conversions.
258 (define_mode_attr V_CVTTO [(V2SI "V2SF") (V2SF "V2SI")
259 (V4SI "V4SF") (V4SF "V4SI")])
261 ;; Define element mode for each vector mode.
262 (define_mode_attr V_elem [(V8QI "QI") (V16QI "QI")
263 (V4HI "HI") (V8HI "HI")
264 (V2SI "SI") (V4SI "SI")
265 (V2SF "SF") (V4SF "SF")
266 (DI "DI") (V2DI "DI")])
268 ;; Element modes for vector extraction, padded up to register size.
270 (define_mode_attr V_ext [(V8QI "SI") (V16QI "SI")
271 (V4HI "SI") (V8HI "SI")
272 (V2SI "SI") (V4SI "SI")
273 (V2SF "SF") (V4SF "SF")
274 (DI "DI") (V2DI "DI")])
276 ;; Mode of pair of elements for each vector mode, to define transfer
277 ;; size for structure lane/dup loads and stores.
278 (define_mode_attr V_two_elem [(V8QI "HI") (V16QI "HI")
279 (V4HI "SI") (V8HI "SI")
280 (V2SI "V2SI") (V4SI "V2SI")
281 (V2SF "V2SF") (V4SF "V2SF")
282 (DI "V2DI") (V2DI "V2DI")])
284 ;; Similar, for three elements.
285 ;; ??? Should we define extra modes so that sizes of all three-element
286 ;; accesses can be accurately represented?
287 (define_mode_attr V_three_elem [(V8QI "SI") (V16QI "SI")
288 (V4HI "V4HI") (V8HI "V4HI")
289 (V2SI "V4SI") (V4SI "V4SI")
290 (V2SF "V4SF") (V4SF "V4SF")
291 (DI "EI") (V2DI "EI")])
293 ;; Similar, for four elements.
294 (define_mode_attr V_four_elem [(V8QI "SI") (V16QI "SI")
295 (V4HI "V4HI") (V8HI "V4HI")
296 (V2SI "V4SI") (V4SI "V4SI")
297 (V2SF "V4SF") (V4SF "V4SF")
298 (DI "OI") (V2DI "OI")])
300 ;; Register width from element mode
301 (define_mode_attr V_reg [(V8QI "P") (V16QI "q")
302 (V4HI "P") (V8HI "q")
303 (V2SI "P") (V4SI "q")
304 (V2SF "P") (V4SF "q")
305 (DI "P") (V2DI "q")])
307 ;; Wider modes with the same number of elements.
308 (define_mode_attr V_widen [(V8QI "V8HI") (V4HI "V4SI") (V2SI "V2DI")])
310 ;; Narrower modes with the same number of elements.
311 (define_mode_attr V_narrow [(V8HI "V8QI") (V4SI "V4HI") (V2DI "V2SI")])
313 ;; Modes with half the number of equal-sized elements.
314 (define_mode_attr V_HALF [(V16QI "V8QI") (V8HI "V4HI")
315 (V4SI "V2SI") (V4SF "V2SF")
318 ;; Same, but lower-case.
319 (define_mode_attr V_half [(V16QI "v8qi") (V8HI "v4hi")
320 (V4SI "v2si") (V4SF "v2sf")
323 ;; Modes with twice the number of equal-sized elements.
324 (define_mode_attr V_DOUBLE [(V8QI "V16QI") (V4HI "V8HI")
325 (V2SI "V4SI") (V2SF "V4SF")
328 ;; Same, but lower-case.
329 (define_mode_attr V_double [(V8QI "v16qi") (V4HI "v8hi")
330 (V2SI "v4si") (V2SF "v4sf")
333 ;; Modes with double-width elements.
334 (define_mode_attr V_double_width [(V8QI "V4HI") (V16QI "V8HI")
335 (V4HI "V2SI") (V8HI "V4SI")
336 (V2SI "DI") (V4SI "V2DI")])
338 ;; Mode of result of comparison operations (and bit-select operand 1).
339 (define_mode_attr V_cmp_result [(V8QI "V8QI") (V16QI "V16QI")
340 (V4HI "V4HI") (V8HI "V8HI")
341 (V2SI "V2SI") (V4SI "V4SI")
342 (V2SF "V2SI") (V4SF "V4SI")
343 (DI "DI") (V2DI "V2DI")])
345 ;; Get element type from double-width mode, for operations where we don't care
347 (define_mode_attr V_if_elem [(V8QI "i8") (V16QI "i8")
348 (V4HI "i16") (V8HI "i16")
349 (V2SI "i32") (V4SI "i32")
350 (DI "i64") (V2DI "i64")
351 (V2SF "f32") (V4SF "f32")])
353 ;; Same, but for operations which work on signed values.
354 (define_mode_attr V_s_elem [(V8QI "s8") (V16QI "s8")
355 (V4HI "s16") (V8HI "s16")
356 (V2SI "s32") (V4SI "s32")
357 (DI "s64") (V2DI "s64")
358 (V2SF "f32") (V4SF "f32")])
360 ;; Same, but for operations which work on unsigned values.
361 (define_mode_attr V_u_elem [(V8QI "u8") (V16QI "u8")
362 (V4HI "u16") (V8HI "u16")
363 (V2SI "u32") (V4SI "u32")
364 (DI "u64") (V2DI "u64")
365 (V2SF "f32") (V4SF "f32")])
367 ;; Element types for extraction of unsigned scalars.
368 (define_mode_attr V_uf_sclr [(V8QI "u8") (V16QI "u8")
369 (V4HI "u16") (V8HI "u16")
370 (V2SI "32") (V4SI "32")
371 (V2SF "32") (V4SF "32")])
373 (define_mode_attr V_sz_elem [(V8QI "8") (V16QI "8")
374 (V4HI "16") (V8HI "16")
375 (V2SI "32") (V4SI "32")
376 (DI "64") (V2DI "64")
377 (V2SF "32") (V4SF "32")])
379 ;; Element sizes for duplicating ARM registers to all elements of a vector.
380 (define_mode_attr VD_dup [(V8QI "8") (V4HI "16") (V2SI "32") (V2SF "32")])
382 ;; Opaque integer types for results of pair-forming intrinsics (vtrn, etc.)
383 (define_mode_attr V_PAIR [(V8QI "TI") (V16QI "OI")
384 (V4HI "TI") (V8HI "OI")
385 (V2SI "TI") (V4SI "OI")
386 (V2SF "TI") (V4SF "OI")
387 (DI "TI") (V2DI "OI")])
389 ;; Same, but lower-case.
390 (define_mode_attr V_pair [(V8QI "ti") (V16QI "oi")
391 (V4HI "ti") (V8HI "oi")
392 (V2SI "ti") (V4SI "oi")
393 (V2SF "ti") (V4SF "oi")
394 (DI "ti") (V2DI "oi")])
396 ;; Operations on two halves of a quadword vector.
397 (define_code_iterator vqh_ops [plus smin smax umin umax])
399 ;; Same, without unsigned variants (for use with *SFmode pattern).
400 (define_code_iterator vqhs_ops [plus smin smax])
402 ;; Assembler mnemonics for above codes.
403 (define_code_attr VQH_mnem [(plus "vadd") (smin "vmin") (smax "vmax")
404 (umin "vmin") (umax "vmax")])
406 ;; Signs of above, where relevant.
407 (define_code_attr VQH_sign [(plus "i") (smin "s") (smax "s") (umin "u")
410 ;; Extra suffix on some 64-bit insn names (to avoid collision with standard
411 ;; names which we don't want to define).
412 (define_mode_attr V_suf64 [(V8QI "") (V16QI "")
416 (DI "_neon") (V2DI "")])
418 ;; Scalars to be presented to scalar multiplication instructions
419 ;; must satisfy the following constraints.
420 ;; 1. If the mode specifies 16-bit elements, the scalar must be in D0-D7.
421 ;; 2. If the mode specifies 32-bit elements, the scalar must be in D0-D15.
422 ;; This mode attribute is used to obtain the correct register constraints.
423 (define_mode_attr scalar_mul_constraint [(V4HI "x") (V2SI "t") (V2SF "t")
424 (V8HI "x") (V4SI "t") (V4SF "t")])
426 ;; Attribute used to permit string comparisons against <VQH_mnem> in
427 ;; neon_type attribute definitions.
428 (define_attr "vqh_mnem" "vadd,vmin,vmax" (const_string "vadd"))
430 ;; Classification of NEON instructions for scheduling purposes.
431 ;; Do not set this attribute and the "type" attribute together in
432 ;; any one instruction pattern.
433 (define_attr "neon_type"
444 neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
445 neon_mul_qqq_8_16_32_ddd_32,\
446 neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
447 neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
449 neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
450 neon_mla_qqq_32_qqd_32_scalar,\
451 neon_mul_ddd_16_scalar_32_16_long_scalar,\
452 neon_mul_qqd_32_scalar,\
453 neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\
458 neon_vqshl_vrshl_vqrshl_qqq,\
460 neon_fp_vadd_ddd_vabs_dd,\
461 neon_fp_vadd_qqq_vabs_qq,\
467 neon_fp_vmla_ddd_scalar,\
468 neon_fp_vmla_qqq_scalar,\
469 neon_fp_vrecps_vrsqrts_ddd,\
470 neon_fp_vrecps_vrsqrts_qqq,\
478 neon_vld2_2_regs_vld1_vld2_all_lanes,\
481 neon_vst1_1_2_regs_vst2_2_regs,\
483 neon_vst2_4_regs_vst3_vst4,\
485 neon_vld1_vld2_lane,\
486 neon_vld3_vld4_lane,\
487 neon_vst1_vst2_lane,\
488 neon_vst3_vst4_lane,\
489 neon_vld3_vld4_all_lanes,\
497 (const_string "none"))
499 ;; Predicates used for setting the above attribute.
501 (define_mode_attr Is_float_mode [(V8QI "false") (V16QI "false")
502 (V4HI "false") (V8HI "false")
503 (V2SI "false") (V4SI "false")
504 (V2SF "true") (V4SF "true")
505 (DI "false") (V2DI "false")])
507 (define_mode_attr Scalar_mul_8_16 [(V8QI "true") (V16QI "true")
508 (V4HI "true") (V8HI "true")
509 (V2SI "false") (V4SI "false")
510 (V2SF "false") (V4SF "false")
511 (DI "false") (V2DI "false")])
514 (define_mode_attr Is_d_reg [(V8QI "true") (V16QI "false")
515 (V4HI "true") (V8HI "false")
516 (V2SI "true") (V4SI "false")
517 (V2SF "true") (V4SF "false")
518 (DI "true") (V2DI "false")])
520 (define_mode_attr V_mode_nunits [(V8QI "8") (V16QI "16")
521 (V4HI "4") (V8HI "8")
522 (V2SI "2") (V4SI "4")
523 (V2SF "2") (V4SF "4")
524 (DI "1") (V2DI "2")])
526 (define_insn "*neon_mov<mode>"
527 [(set (match_operand:VD 0 "nonimmediate_operand"
528 "=w,Uv,w, w, ?r,?w,?r,?r, ?Us")
529 (match_operand:VD 1 "general_operand"
530 " w,w, Dn,Uvi, w, r, r, Usi,r"))]
533 if (which_alternative == 2)
536 static char templ[40];
538 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
539 &operands[1], &width);
541 gcc_assert (is_valid != 0);
544 return "vmov.f32\t%P0, %1 @ <mode>";
546 sprintf (templ, "vmov.i%d\t%%P0, %%1 @ <mode>", width);
551 /* FIXME: If the memory layout is changed in big-endian mode, output_move_vfp
552 below must be changed to output_move_neon (which will use the
553 element/structure loads/stores), and the constraint changed to 'Un' instead
556 switch (which_alternative)
558 case 0: return "vmov\t%P0, %P1 @ <mode>";
559 case 1: case 3: return output_move_vfp (operands);
560 case 2: gcc_unreachable ();
561 case 4: return "vmov\t%Q0, %R0, %P1 @ <mode>";
562 case 5: return "vmov\t%P0, %Q1, %R1 @ <mode>";
563 default: return output_move_double (operands);
566 [(set_attr "neon_type" "neon_int_1,*,neon_vmov,*,neon_mrrc,neon_mcr_2_mcrr,*,*,*")
567 (set_attr "type" "*,f_stored,*,f_loadd,*,*,alu,load2,store2")
568 (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
569 (set_attr "length" "4,4,4,4,4,4,8,8,8")
570 (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
571 (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
573 (define_insn "*neon_mov<mode>"
574 [(set (match_operand:VQXMOV 0 "nonimmediate_operand"
575 "=w,Un,w, w, ?r,?w,?r,?r, ?Us")
576 (match_operand:VQXMOV 1 "general_operand"
577 " w,w, Dn,Uni, w, r, r, Usi, r"))]
580 if (which_alternative == 2)
583 static char templ[40];
585 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
586 &operands[1], &width);
588 gcc_assert (is_valid != 0);
591 return "vmov.f32\t%q0, %1 @ <mode>";
593 sprintf (templ, "vmov.i%d\t%%q0, %%1 @ <mode>", width);
598 switch (which_alternative)
600 case 0: return "vmov\t%q0, %q1 @ <mode>";
601 case 1: case 3: return output_move_neon (operands);
602 case 2: gcc_unreachable ();
603 case 4: return "vmov\t%Q0, %R0, %e1 @ <mode>\;vmov\t%J0, %K0, %f1";
604 case 5: return "vmov\t%e0, %Q1, %R1 @ <mode>\;vmov\t%f0, %J1, %K1";
605 default: return output_move_quad (operands);
608 [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\
609 neon_mrrc,neon_mcr_2_mcrr,*,*,*")
610 (set_attr "type" "*,*,*,*,*,*,alu,load4,store4")
611 (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
612 (set_attr "length" "4,8,4,8,8,8,16,8,16")
613 (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
614 (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
616 (define_expand "movti"
617 [(set (match_operand:TI 0 "nonimmediate_operand" "")
618 (match_operand:TI 1 "general_operand" ""))]
623 (define_expand "mov<mode>"
624 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "")
625 (match_operand:VSTRUCT 1 "general_operand" ""))]
630 (define_insn "*neon_mov<mode>"
631 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "=w,Ut,w")
632 (match_operand:VSTRUCT 1 "general_operand" " w,w, Ut"))]
635 switch (which_alternative)
638 case 1: case 2: return output_move_neon (operands);
639 default: gcc_unreachable ();
642 [(set_attr "length" "<V_slen>,<V_slen>,<V_slen>")])
645 [(set (match_operand:EI 0 "s_register_operand" "")
646 (match_operand:EI 1 "s_register_operand" ""))]
647 "TARGET_NEON && reload_completed"
648 [(set (match_dup 0) (match_dup 1))
649 (set (match_dup 2) (match_dup 3))]
651 int rdest = REGNO (operands[0]);
652 int rsrc = REGNO (operands[1]);
655 dest[0] = gen_rtx_REG (TImode, rdest);
656 src[0] = gen_rtx_REG (TImode, rsrc);
657 dest[1] = gen_rtx_REG (DImode, rdest + 4);
658 src[1] = gen_rtx_REG (DImode, rsrc + 4);
660 neon_disambiguate_copy (operands, dest, src, 2);
664 [(set (match_operand:OI 0 "s_register_operand" "")
665 (match_operand:OI 1 "s_register_operand" ""))]
666 "TARGET_NEON && reload_completed"
667 [(set (match_dup 0) (match_dup 1))
668 (set (match_dup 2) (match_dup 3))]
670 int rdest = REGNO (operands[0]);
671 int rsrc = REGNO (operands[1]);
674 dest[0] = gen_rtx_REG (TImode, rdest);
675 src[0] = gen_rtx_REG (TImode, rsrc);
676 dest[1] = gen_rtx_REG (TImode, rdest + 4);
677 src[1] = gen_rtx_REG (TImode, rsrc + 4);
679 neon_disambiguate_copy (operands, dest, src, 2);
683 [(set (match_operand:CI 0 "s_register_operand" "")
684 (match_operand:CI 1 "s_register_operand" ""))]
685 "TARGET_NEON && reload_completed"
686 [(set (match_dup 0) (match_dup 1))
687 (set (match_dup 2) (match_dup 3))
688 (set (match_dup 4) (match_dup 5))]
690 int rdest = REGNO (operands[0]);
691 int rsrc = REGNO (operands[1]);
694 dest[0] = gen_rtx_REG (TImode, rdest);
695 src[0] = gen_rtx_REG (TImode, rsrc);
696 dest[1] = gen_rtx_REG (TImode, rdest + 4);
697 src[1] = gen_rtx_REG (TImode, rsrc + 4);
698 dest[2] = gen_rtx_REG (TImode, rdest + 8);
699 src[2] = gen_rtx_REG (TImode, rsrc + 8);
701 neon_disambiguate_copy (operands, dest, src, 3);
705 [(set (match_operand:XI 0 "s_register_operand" "")
706 (match_operand:XI 1 "s_register_operand" ""))]
707 "TARGET_NEON && reload_completed"
708 [(set (match_dup 0) (match_dup 1))
709 (set (match_dup 2) (match_dup 3))
710 (set (match_dup 4) (match_dup 5))
711 (set (match_dup 6) (match_dup 7))]
713 int rdest = REGNO (operands[0]);
714 int rsrc = REGNO (operands[1]);
717 dest[0] = gen_rtx_REG (TImode, rdest);
718 src[0] = gen_rtx_REG (TImode, rsrc);
719 dest[1] = gen_rtx_REG (TImode, rdest + 4);
720 src[1] = gen_rtx_REG (TImode, rsrc + 4);
721 dest[2] = gen_rtx_REG (TImode, rdest + 8);
722 src[2] = gen_rtx_REG (TImode, rsrc + 8);
723 dest[3] = gen_rtx_REG (TImode, rdest + 12);
724 src[3] = gen_rtx_REG (TImode, rsrc + 12);
726 neon_disambiguate_copy (operands, dest, src, 4);
729 (define_insn "vec_set<mode>_internal"
730 [(set (match_operand:VD 0 "s_register_operand" "=w")
733 (match_operand:<V_elem> 1 "s_register_operand" "r"))
734 (match_operand:VD 3 "s_register_operand" "0")
735 (match_operand:SI 2 "immediate_operand" "i")))]
738 operands[2] = GEN_INT (ffs ((int) INTVAL (operands[2]) - 1));
740 return "vmov%?.<V_uf_sclr>\t%P0[%c2], %1";
742 [(set_attr "predicable" "yes")
743 (set_attr "neon_type" "neon_mcr")])
745 (define_insn "vec_set<mode>_internal"
746 [(set (match_operand:VQ 0 "s_register_operand" "=w")
749 (match_operand:<V_elem> 1 "s_register_operand" "r"))
750 (match_operand:VQ 3 "s_register_operand" "0")
751 (match_operand:SI 2 "immediate_operand" "i")))]
754 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
755 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
756 int elt = elem % half_elts;
757 int hi = (elem / half_elts) * 2;
758 int regno = REGNO (operands[0]);
760 operands[0] = gen_rtx_REG (<V_HALF>mode, regno + hi);
761 operands[2] = GEN_INT (elt);
763 return "vmov%?.<V_uf_sclr>\t%P0[%c2], %1";
765 [(set_attr "predicable" "yes")
766 (set_attr "neon_type" "neon_mcr")]
769 (define_insn "vec_setv2di_internal"
770 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
773 (match_operand:DI 1 "s_register_operand" "r"))
774 (match_operand:V2DI 3 "s_register_operand" "0")
775 (match_operand:SI 2 "immediate_operand" "i")))]
778 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
779 int regno = REGNO (operands[0]) + 2 * elem;
781 operands[0] = gen_rtx_REG (DImode, regno);
783 return "vmov%?.64\t%P0, %Q1, %R1";
785 [(set_attr "predicable" "yes")
786 (set_attr "neon_type" "neon_mcr_2_mcrr")]
789 (define_expand "vec_set<mode>"
790 [(match_operand:VDQ 0 "s_register_operand" "")
791 (match_operand:<V_elem> 1 "s_register_operand" "")
792 (match_operand:SI 2 "immediate_operand" "")]
795 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
796 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
797 GEN_INT (elem), operands[0]));
801 (define_insn "vec_extract<mode>"
802 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
804 (match_operand:VD 1 "s_register_operand" "w")
805 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
807 "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]"
808 [(set_attr "predicable" "yes")
809 (set_attr "neon_type" "neon_bp_simple")]
812 (define_insn "vec_extract<mode>"
813 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
815 (match_operand:VQ 1 "s_register_operand" "w")
816 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
819 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
820 int elt = INTVAL (operands[2]) % half_elts;
821 int hi = (INTVAL (operands[2]) / half_elts) * 2;
822 int regno = REGNO (operands[1]);
824 operands[1] = gen_rtx_REG (<V_HALF>mode, regno + hi);
825 operands[2] = GEN_INT (elt);
827 return "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]";
829 [(set_attr "predicable" "yes")
830 (set_attr "neon_type" "neon_bp_simple")]
833 (define_insn "vec_extractv2di"
834 [(set (match_operand:DI 0 "s_register_operand" "=r")
836 (match_operand:V2DI 1 "s_register_operand" "w")
837 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
840 int regno = REGNO (operands[1]) + INTVAL (operands[2]);
842 operands[1] = gen_rtx_REG (DImode, regno);
844 return "vmov%?.64\t%Q0, %R0, %P1";
846 [(set_attr "predicable" "yes")
847 (set_attr "neon_type" "neon_int_1")]
850 (define_expand "vec_init<mode>"
851 [(match_operand:VDQ 0 "s_register_operand" "")
852 (match_operand 1 "" "")]
855 neon_expand_vector_init (operands[0], operands[1]);
859 ;; Doubleword and quadword arithmetic.
861 ;; NOTE: vadd/vsub and some other instructions also support 64-bit integer
862 ;; element size, which we could potentially use for "long long" operations. We
863 ;; don't want to do this at present though, because moving values from the
864 ;; vector unit to the ARM core is currently slow and 64-bit addition (etc.) is
865 ;; easy to do with ARM instructions anyway.
867 (define_insn "*add<mode>3_neon"
868 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
869 (plus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
870 (match_operand:VDQ 2 "s_register_operand" "w")))]
872 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
873 [(set (attr "neon_type")
874 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
875 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
876 (const_string "neon_fp_vadd_ddd_vabs_dd")
877 (const_string "neon_fp_vadd_qqq_vabs_qq"))
878 (const_string "neon_int_1")))]
881 (define_insn "*sub<mode>3_neon"
882 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
883 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
884 (match_operand:VDQ 2 "s_register_operand" "w")))]
886 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
887 [(set (attr "neon_type")
888 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
889 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
890 (const_string "neon_fp_vadd_ddd_vabs_dd")
891 (const_string "neon_fp_vadd_qqq_vabs_qq"))
892 (const_string "neon_int_2")))]
895 (define_insn "*mul<mode>3_neon"
896 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
897 (mult:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
898 (match_operand:VDQ 2 "s_register_operand" "w")))]
900 "vmul.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
901 [(set (attr "neon_type")
902 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
903 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
904 (const_string "neon_fp_vadd_ddd_vabs_dd")
905 (const_string "neon_fp_vadd_qqq_vabs_qq"))
906 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
908 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
909 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
910 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
911 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
912 (const_string "neon_mul_qqq_8_16_32_ddd_32")
913 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
916 (define_insn "ior<mode>3"
917 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
918 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
919 (match_operand:VDQ 2 "neon_logic_op2" "w,Dl")))]
922 switch (which_alternative)
924 case 0: return "vorr\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
925 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
926 <MODE>mode, 0, VALID_NEON_QREG_MODE (<MODE>mode));
927 default: gcc_unreachable ();
930 [(set_attr "neon_type" "neon_int_1")]
933 (define_insn "iordi3_neon"
934 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
935 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w,0")
936 (match_operand:DI 2 "neon_logic_op2" "w,Dl")]
940 switch (which_alternative)
942 case 0: return "vorr\t%P0, %P1, %P2";
943 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
944 DImode, 0, VALID_NEON_QREG_MODE (DImode));
945 default: gcc_unreachable ();
948 [(set_attr "neon_type" "neon_int_1")]
951 ;; The concrete forms of the Neon immediate-logic instructions are vbic and
952 ;; vorr. We support the pseudo-instruction vand instead, because that
953 ;; corresponds to the canonical form the middle-end expects to use for
954 ;; immediate bitwise-ANDs.
956 (define_insn "and<mode>3"
957 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
958 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
959 (match_operand:VDQ 2 "neon_inv_logic_op2" "w,DL")))]
962 switch (which_alternative)
964 case 0: return "vand\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
965 case 1: return neon_output_logic_immediate ("vand", &operands[2],
966 <MODE>mode, 1, VALID_NEON_QREG_MODE (<MODE>mode));
967 default: gcc_unreachable ();
970 [(set_attr "neon_type" "neon_int_1")]
973 (define_insn "anddi3_neon"
974 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
975 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w,0")
976 (match_operand:DI 2 "neon_inv_logic_op2" "w,DL")]
980 switch (which_alternative)
982 case 0: return "vand\t%P0, %P1, %P2";
983 case 1: return neon_output_logic_immediate ("vand", &operands[2],
984 DImode, 1, VALID_NEON_QREG_MODE (DImode));
985 default: gcc_unreachable ();
988 [(set_attr "neon_type" "neon_int_1")]
991 (define_insn "orn<mode>3_neon"
992 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
993 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
994 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
996 "vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
997 [(set_attr "neon_type" "neon_int_1")]
1000 (define_insn "orndi3_neon"
1001 [(set (match_operand:DI 0 "s_register_operand" "=w")
1002 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
1003 (match_operand:DI 2 "s_register_operand" "w")]
1006 "vorn\t%P0, %P1, %P2"
1007 [(set_attr "neon_type" "neon_int_1")]
1010 (define_insn "bic<mode>3_neon"
1011 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1012 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
1013 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
1015 "vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1016 [(set_attr "neon_type" "neon_int_1")]
1019 (define_insn "bicdi3_neon"
1020 [(set (match_operand:DI 0 "s_register_operand" "=w")
1021 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
1022 (match_operand:DI 2 "s_register_operand" "w")]
1025 "vbic\t%P0, %P1, %P2"
1026 [(set_attr "neon_type" "neon_int_1")]
1029 (define_insn "xor<mode>3"
1030 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1031 (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
1032 (match_operand:VDQ 2 "s_register_operand" "w")))]
1034 "veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1035 [(set_attr "neon_type" "neon_int_1")]
1038 (define_insn "xordi3_neon"
1039 [(set (match_operand:DI 0 "s_register_operand" "=w")
1040 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
1041 (match_operand:DI 2 "s_register_operand" "w")]
1044 "veor\t%P0, %P1, %P2"
1045 [(set_attr "neon_type" "neon_int_1")]
1048 (define_insn "one_cmpl<mode>2"
1049 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1050 (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
1052 "vmvn\t%<V_reg>0, %<V_reg>1"
1053 [(set_attr "neon_type" "neon_int_1")]
1056 (define_insn "abs<mode>2"
1057 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1058 (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
1060 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
1061 [(set (attr "neon_type")
1062 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1063 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1064 (const_string "neon_fp_vadd_ddd_vabs_dd")
1065 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1066 (const_string "neon_int_3")))]
1069 (define_insn "neg<mode>2"
1070 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1071 (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
1073 "vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
1074 [(set (attr "neon_type")
1075 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1076 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1077 (const_string "neon_fp_vadd_ddd_vabs_dd")
1078 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1079 (const_string "neon_int_3")))]
1082 (define_insn "*umin<mode>3_neon"
1083 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1084 (umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1085 (match_operand:VDQIW 2 "s_register_operand" "w")))]
1087 "vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1088 [(set_attr "neon_type" "neon_int_5")]
1091 (define_insn "*umax<mode>3_neon"
1092 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1093 (umax:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1094 (match_operand:VDQIW 2 "s_register_operand" "w")))]
1096 "vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1097 [(set_attr "neon_type" "neon_int_5")]
1100 (define_insn "*smin<mode>3_neon"
1101 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1102 (smin:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
1103 (match_operand:VDQW 2 "s_register_operand" "w")))]
1105 "vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1106 [(set (attr "neon_type")
1107 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1108 (const_string "neon_fp_vadd_ddd_vabs_dd")
1109 (const_string "neon_int_5")))]
1112 (define_insn "*smax<mode>3_neon"
1113 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1114 (smax:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
1115 (match_operand:VDQW 2 "s_register_operand" "w")))]
1117 "vmax.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1118 [(set (attr "neon_type")
1119 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1120 (const_string "neon_fp_vadd_ddd_vabs_dd")
1121 (const_string "neon_int_5")))]
1124 ; TODO: V2DI shifts are current disabled because there are bugs in the
1125 ; generic vectorizer code. It ends up creating a V2DI constructor with
1128 (define_insn "ashl<mode>3"
1129 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1130 (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1131 (match_operand:VDQIW 2 "s_register_operand" "w")))]
1133 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1134 [(set (attr "neon_type")
1135 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1136 (const_string "neon_vshl_ddd")
1137 (const_string "neon_shift_3")))]
1140 ; Used for implementing logical shift-right, which is a left-shift by a negative
1141 ; amount, with signed operands. This is essentially the same as ashl<mode>3
1142 ; above, but using an unspec in case GCC tries anything tricky with negative
1145 (define_insn "ashl<mode>3_signed"
1146 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
1147 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
1148 (match_operand:VDQI 2 "s_register_operand" "w")]
1149 UNSPEC_ASHIFT_SIGNED))]
1151 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1152 [(set (attr "neon_type")
1153 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1154 (const_string "neon_vshl_ddd")
1155 (const_string "neon_shift_3")))]
1158 ; Used for implementing logical shift-right, which is a left-shift by a negative
1159 ; amount, with unsigned operands.
1161 (define_insn "ashl<mode>3_unsigned"
1162 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
1163 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
1164 (match_operand:VDQI 2 "s_register_operand" "w")]
1165 UNSPEC_ASHIFT_UNSIGNED))]
1167 "vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1168 [(set (attr "neon_type")
1169 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1170 (const_string "neon_vshl_ddd")
1171 (const_string "neon_shift_3")))]
1174 (define_expand "ashr<mode>3"
1175 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1176 (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1177 (match_operand:VDQIW 2 "s_register_operand" "")))]
1180 rtx neg = gen_reg_rtx (<MODE>mode);
1182 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1183 emit_insn (gen_ashl<mode>3_signed (operands[0], operands[1], neg));
1188 (define_expand "lshr<mode>3"
1189 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1190 (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1191 (match_operand:VDQIW 2 "s_register_operand" "")))]
1194 rtx neg = gen_reg_rtx (<MODE>mode);
1196 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1197 emit_insn (gen_ashl<mode>3_unsigned (operands[0], operands[1], neg));
1202 ;; Widening operations
1204 (define_insn "widen_ssum<mode>3"
1205 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1206 (plus:<V_widen> (sign_extend:<V_widen>
1207 (match_operand:VW 1 "s_register_operand" "%w"))
1208 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1210 "vaddw.<V_s_elem>\t%q0, %q2, %P1"
1211 [(set_attr "neon_type" "neon_int_3")]
1214 (define_insn "widen_usum<mode>3"
1215 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1216 (plus:<V_widen> (zero_extend:<V_widen>
1217 (match_operand:VW 1 "s_register_operand" "%w"))
1218 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1220 "vaddw.<V_u_elem>\t%q0, %q2, %P1"
1221 [(set_attr "neon_type" "neon_int_3")]
1224 ;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
1225 ;; shift-count granularity. That's good enough for the middle-end's current
1228 (define_expand "vec_shr_<mode>"
1229 [(match_operand:VDQ 0 "s_register_operand" "")
1230 (match_operand:VDQ 1 "s_register_operand" "")
1231 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1235 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1236 const int width = GET_MODE_BITSIZE (<MODE>mode);
1237 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1238 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1239 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1241 if (num_bits == width)
1243 emit_move_insn (operands[0], operands[1]);
1247 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1248 operands[0] = gen_lowpart (bvecmode, operands[0]);
1249 operands[1] = gen_lowpart (bvecmode, operands[1]);
1251 emit_insn (gen_ext (operands[0], operands[1], zero_reg,
1252 GEN_INT (num_bits / BITS_PER_UNIT)));
1256 (define_expand "vec_shl_<mode>"
1257 [(match_operand:VDQ 0 "s_register_operand" "")
1258 (match_operand:VDQ 1 "s_register_operand" "")
1259 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1263 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1264 const int width = GET_MODE_BITSIZE (<MODE>mode);
1265 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1266 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1267 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1271 emit_move_insn (operands[0], CONST0_RTX (<MODE>mode));
1275 num_bits = width - num_bits;
1277 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1278 operands[0] = gen_lowpart (bvecmode, operands[0]);
1279 operands[1] = gen_lowpart (bvecmode, operands[1]);
1281 emit_insn (gen_ext (operands[0], zero_reg, operands[1],
1282 GEN_INT (num_bits / BITS_PER_UNIT)));
1286 ;; Helpers for quad-word reduction operations
1288 ; Add (or smin, smax...) the low N/2 elements of the N-element vector
1289 ; operand[1] to the high N/2 elements of same. Put the result in operand[0], an
1290 ; N/2-element vector.
1292 (define_insn "quad_halves_<code>v4si"
1293 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
1295 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
1296 (parallel [(const_int 0) (const_int 1)]))
1297 (vec_select:V2SI (match_dup 1)
1298 (parallel [(const_int 2) (const_int 3)]))))]
1300 "<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1"
1301 [(set_attr "vqh_mnem" "<VQH_mnem>")
1302 (set (attr "neon_type")
1303 (if_then_else (eq_attr "vqh_mnem" "vadd")
1304 (const_string "neon_int_1") (const_string "neon_int_5")))]
1307 (define_insn "quad_halves_<code>v4sf"
1308 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
1310 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
1311 (parallel [(const_int 0) (const_int 1)]))
1312 (vec_select:V2SF (match_dup 1)
1313 (parallel [(const_int 2) (const_int 3)]))))]
1315 "<VQH_mnem>.f32\t%P0, %e1, %f1"
1316 [(set_attr "vqh_mnem" "<VQH_mnem>")
1317 (set (attr "neon_type")
1318 (if_then_else (eq_attr "vqh_mnem" "vadd")
1319 (const_string "neon_int_1") (const_string "neon_int_5")))]
1322 (define_insn "quad_halves_<code>v8hi"
1323 [(set (match_operand:V4HI 0 "s_register_operand" "+w")
1325 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
1326 (parallel [(const_int 0) (const_int 1)
1327 (const_int 2) (const_int 3)]))
1328 (vec_select:V4HI (match_dup 1)
1329 (parallel [(const_int 4) (const_int 5)
1330 (const_int 6) (const_int 7)]))))]
1332 "<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1"
1333 [(set_attr "vqh_mnem" "<VQH_mnem>")
1334 (set (attr "neon_type")
1335 (if_then_else (eq_attr "vqh_mnem" "vadd")
1336 (const_string "neon_int_1") (const_string "neon_int_5")))]
1339 (define_insn "quad_halves_<code>v16qi"
1340 [(set (match_operand:V8QI 0 "s_register_operand" "+w")
1342 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
1343 (parallel [(const_int 0) (const_int 1)
1344 (const_int 2) (const_int 3)
1345 (const_int 4) (const_int 5)
1346 (const_int 6) (const_int 7)]))
1347 (vec_select:V8QI (match_dup 1)
1348 (parallel [(const_int 8) (const_int 9)
1349 (const_int 10) (const_int 11)
1350 (const_int 12) (const_int 13)
1351 (const_int 14) (const_int 15)]))))]
1353 "<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1"
1354 [(set_attr "vqh_mnem" "<VQH_mnem>")
1355 (set (attr "neon_type")
1356 (if_then_else (eq_attr "vqh_mnem" "vadd")
1357 (const_string "neon_int_1") (const_string "neon_int_5")))]
1360 ; FIXME: We wouldn't need the following insns if we could write subregs of
1361 ; vector registers. Make an attempt at removing unnecessary moves, though
1362 ; we're really at the mercy of the register allocator.
1364 (define_insn "move_lo_quad_v4si"
1365 [(set (match_operand:V4SI 0 "s_register_operand" "+w")
1367 (match_operand:V2SI 1 "s_register_operand" "w")
1368 (vec_select:V2SI (match_dup 0)
1369 (parallel [(const_int 2) (const_int 3)]))))]
1372 int dest = REGNO (operands[0]);
1373 int src = REGNO (operands[1]);
1376 return "vmov\t%e0, %P1";
1380 [(set_attr "neon_type" "neon_bp_simple")]
1383 (define_insn "move_lo_quad_v4sf"
1384 [(set (match_operand:V4SF 0 "s_register_operand" "+w")
1386 (match_operand:V2SF 1 "s_register_operand" "w")
1387 (vec_select:V2SF (match_dup 0)
1388 (parallel [(const_int 2) (const_int 3)]))))]
1391 int dest = REGNO (operands[0]);
1392 int src = REGNO (operands[1]);
1395 return "vmov\t%e0, %P1";
1399 [(set_attr "neon_type" "neon_bp_simple")]
1402 (define_insn "move_lo_quad_v8hi"
1403 [(set (match_operand:V8HI 0 "s_register_operand" "+w")
1405 (match_operand:V4HI 1 "s_register_operand" "w")
1406 (vec_select:V4HI (match_dup 0)
1407 (parallel [(const_int 4) (const_int 5)
1408 (const_int 6) (const_int 7)]))))]
1411 int dest = REGNO (operands[0]);
1412 int src = REGNO (operands[1]);
1415 return "vmov\t%e0, %P1";
1419 [(set_attr "neon_type" "neon_bp_simple")]
1422 (define_insn "move_lo_quad_v16qi"
1423 [(set (match_operand:V16QI 0 "s_register_operand" "+w")
1425 (match_operand:V8QI 1 "s_register_operand" "w")
1426 (vec_select:V8QI (match_dup 0)
1427 (parallel [(const_int 8) (const_int 9)
1428 (const_int 10) (const_int 11)
1429 (const_int 12) (const_int 13)
1430 (const_int 14) (const_int 15)]))))]
1433 int dest = REGNO (operands[0]);
1434 int src = REGNO (operands[1]);
1437 return "vmov\t%e0, %P1";
1441 [(set_attr "neon_type" "neon_bp_simple")]
1444 ;; Reduction operations
1446 (define_expand "reduc_splus_<mode>"
1447 [(match_operand:VD 0 "s_register_operand" "")
1448 (match_operand:VD 1 "s_register_operand" "")]
1451 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1452 &gen_neon_vpadd_internal<mode>);
1456 (define_expand "reduc_splus_<mode>"
1457 [(match_operand:VQ 0 "s_register_operand" "")
1458 (match_operand:VQ 1 "s_register_operand" "")]
1461 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1462 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1464 emit_insn (gen_quad_halves_plus<mode> (step1, operands[1]));
1465 emit_insn (gen_reduc_splus_<V_half> (res_d, step1));
1466 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1471 (define_insn "reduc_splus_v2di"
1472 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1473 (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")]
1476 "vadd.i64\t%e0, %e1, %f1"
1477 [(set_attr "neon_type" "neon_int_1")]
1480 ;; NEON does not distinguish between signed and unsigned addition except on
1481 ;; widening operations.
1482 (define_expand "reduc_uplus_<mode>"
1483 [(match_operand:VDQI 0 "s_register_operand" "")
1484 (match_operand:VDQI 1 "s_register_operand" "")]
1487 emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1]));
1491 (define_expand "reduc_smin_<mode>"
1492 [(match_operand:VD 0 "s_register_operand" "")
1493 (match_operand:VD 1 "s_register_operand" "")]
1496 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1497 &gen_neon_vpsmin<mode>);
1501 (define_expand "reduc_smin_<mode>"
1502 [(match_operand:VQ 0 "s_register_operand" "")
1503 (match_operand:VQ 1 "s_register_operand" "")]
1506 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1507 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1509 emit_insn (gen_quad_halves_smin<mode> (step1, operands[1]));
1510 emit_insn (gen_reduc_smin_<V_half> (res_d, step1));
1511 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1516 (define_expand "reduc_smax_<mode>"
1517 [(match_operand:VD 0 "s_register_operand" "")
1518 (match_operand:VD 1 "s_register_operand" "")]
1521 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1522 &gen_neon_vpsmax<mode>);
1526 (define_expand "reduc_smax_<mode>"
1527 [(match_operand:VQ 0 "s_register_operand" "")
1528 (match_operand:VQ 1 "s_register_operand" "")]
1531 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1532 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1534 emit_insn (gen_quad_halves_smax<mode> (step1, operands[1]));
1535 emit_insn (gen_reduc_smax_<V_half> (res_d, step1));
1536 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1541 (define_expand "reduc_umin_<mode>"
1542 [(match_operand:VDI 0 "s_register_operand" "")
1543 (match_operand:VDI 1 "s_register_operand" "")]
1546 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1547 &gen_neon_vpumin<mode>);
1551 (define_expand "reduc_umin_<mode>"
1552 [(match_operand:VQI 0 "s_register_operand" "")
1553 (match_operand:VQI 1 "s_register_operand" "")]
1556 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1557 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1559 emit_insn (gen_quad_halves_umin<mode> (step1, operands[1]));
1560 emit_insn (gen_reduc_umin_<V_half> (res_d, step1));
1561 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1566 (define_expand "reduc_umax_<mode>"
1567 [(match_operand:VDI 0 "s_register_operand" "")
1568 (match_operand:VDI 1 "s_register_operand" "")]
1571 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1572 &gen_neon_vpumax<mode>);
1576 (define_expand "reduc_umax_<mode>"
1577 [(match_operand:VQI 0 "s_register_operand" "")
1578 (match_operand:VQI 1 "s_register_operand" "")]
1581 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1582 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1584 emit_insn (gen_quad_halves_umax<mode> (step1, operands[1]));
1585 emit_insn (gen_reduc_umax_<V_half> (res_d, step1));
1586 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1591 (define_insn "neon_vpadd_internal<mode>"
1592 [(set (match_operand:VD 0 "s_register_operand" "=w")
1593 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1594 (match_operand:VD 2 "s_register_operand" "w")]
1597 "vpadd.<V_if_elem>\t%P0, %P1, %P2"
1598 ;; Assume this schedules like vadd.
1599 [(set (attr "neon_type")
1600 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1601 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1602 (const_string "neon_fp_vadd_ddd_vabs_dd")
1603 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1604 (const_string "neon_int_1")))]
1607 (define_insn "neon_vpsmin<mode>"
1608 [(set (match_operand:VD 0 "s_register_operand" "=w")
1609 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1610 (match_operand:VD 2 "s_register_operand" "w")]
1613 "vpmin.<V_s_elem>\t%P0, %P1, %P2"
1614 ;; Assume this schedules like vmin.
1615 [(set (attr "neon_type")
1616 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1617 (const_string "neon_fp_vadd_ddd_vabs_dd")
1618 (const_string "neon_int_5")))]
1621 (define_insn "neon_vpsmax<mode>"
1622 [(set (match_operand:VD 0 "s_register_operand" "=w")
1623 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1624 (match_operand:VD 2 "s_register_operand" "w")]
1627 "vpmax.<V_s_elem>\t%P0, %P1, %P2"
1628 ;; Assume this schedules like vmax.
1629 [(set (attr "neon_type")
1630 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1631 (const_string "neon_fp_vadd_ddd_vabs_dd")
1632 (const_string "neon_int_5")))]
1635 (define_insn "neon_vpumin<mode>"
1636 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1637 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1638 (match_operand:VDI 2 "s_register_operand" "w")]
1641 "vpmin.<V_u_elem>\t%P0, %P1, %P2"
1642 ;; Assume this schedules like umin.
1643 [(set_attr "neon_type" "neon_int_5")]
1646 (define_insn "neon_vpumax<mode>"
1647 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1648 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1649 (match_operand:VDI 2 "s_register_operand" "w")]
1652 "vpmax.<V_u_elem>\t%P0, %P1, %P2"
1653 ;; Assume this schedules like umax.
1654 [(set_attr "neon_type" "neon_int_5")]
1657 ;; Saturating arithmetic
1659 ; NOTE: Neon supports many more saturating variants of instructions than the
1660 ; following, but these are all GCC currently understands.
1661 ; FIXME: Actually, GCC doesn't know how to create saturating add/sub by itself
1662 ; yet either, although these patterns may be used by intrinsics when they're
1665 (define_insn "*ss_add<mode>_neon"
1666 [(set (match_operand:VD 0 "s_register_operand" "=w")
1667 (ss_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1668 (match_operand:VD 2 "s_register_operand" "w")))]
1670 "vqadd.<V_s_elem>\t%P0, %P1, %P2"
1671 [(set_attr "neon_type" "neon_int_4")]
1674 (define_insn "*us_add<mode>_neon"
1675 [(set (match_operand:VD 0 "s_register_operand" "=w")
1676 (us_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1677 (match_operand:VD 2 "s_register_operand" "w")))]
1679 "vqadd.<V_u_elem>\t%P0, %P1, %P2"
1680 [(set_attr "neon_type" "neon_int_4")]
1683 (define_insn "*ss_sub<mode>_neon"
1684 [(set (match_operand:VD 0 "s_register_operand" "=w")
1685 (ss_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1686 (match_operand:VD 2 "s_register_operand" "w")))]
1688 "vqsub.<V_s_elem>\t%P0, %P1, %P2"
1689 [(set_attr "neon_type" "neon_int_5")]
1692 (define_insn "*us_sub<mode>_neon"
1693 [(set (match_operand:VD 0 "s_register_operand" "=w")
1694 (us_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1695 (match_operand:VD 2 "s_register_operand" "w")))]
1697 "vqsub.<V_u_elem>\t%P0, %P1, %P2"
1698 [(set_attr "neon_type" "neon_int_5")]
1701 ;; Patterns for builtins.
1703 ; good for plain vadd, vaddq.
1705 (define_insn "neon_vadd<mode>"
1706 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1707 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1708 (match_operand:VDQX 2 "s_register_operand" "w")
1709 (match_operand:SI 3 "immediate_operand" "i")]
1712 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1713 [(set (attr "neon_type")
1714 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1715 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1716 (const_string "neon_fp_vadd_ddd_vabs_dd")
1717 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1718 (const_string "neon_int_1")))]
1721 ; operand 3 represents in bits:
1722 ; bit 0: signed (vs unsigned).
1723 ; bit 1: rounding (vs none).
1725 (define_insn "neon_vaddl<mode>"
1726 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1727 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1728 (match_operand:VDI 2 "s_register_operand" "w")
1729 (match_operand:SI 3 "immediate_operand" "i")]
1732 "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1733 [(set_attr "neon_type" "neon_int_3")]
1736 (define_insn "neon_vaddw<mode>"
1737 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1738 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1739 (match_operand:VDI 2 "s_register_operand" "w")
1740 (match_operand:SI 3 "immediate_operand" "i")]
1743 "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
1744 [(set_attr "neon_type" "neon_int_2")]
1749 (define_insn "neon_vhadd<mode>"
1750 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1751 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1752 (match_operand:VDQIW 2 "s_register_operand" "w")
1753 (match_operand:SI 3 "immediate_operand" "i")]
1756 "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1757 [(set_attr "neon_type" "neon_int_4")]
1760 (define_insn "neon_vqadd<mode>"
1761 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1762 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1763 (match_operand:VDQIX 2 "s_register_operand" "w")
1764 (match_operand:SI 3 "immediate_operand" "i")]
1767 "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1768 [(set_attr "neon_type" "neon_int_4")]
1771 (define_insn "neon_vaddhn<mode>"
1772 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
1773 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
1774 (match_operand:VN 2 "s_register_operand" "w")
1775 (match_operand:SI 3 "immediate_operand" "i")]
1778 "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2"
1779 [(set_attr "neon_type" "neon_int_4")]
1782 (define_insn "neon_vmul<mode>"
1783 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1784 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1785 (match_operand:VDQW 2 "s_register_operand" "w")
1786 (match_operand:SI 3 "immediate_operand" "i")]
1789 "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1790 [(set (attr "neon_type")
1791 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1792 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1793 (const_string "neon_fp_vadd_ddd_vabs_dd")
1794 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1795 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1797 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1798 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1799 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1800 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1801 (const_string "neon_mul_qqq_8_16_32_ddd_32")
1802 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
1805 (define_insn "neon_vmla<mode>"
1806 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1807 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
1808 (match_operand:VDQW 2 "s_register_operand" "w")
1809 (match_operand:VDQW 3 "s_register_operand" "w")
1810 (match_operand:SI 4 "immediate_operand" "i")]
1813 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
1814 [(set (attr "neon_type")
1815 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1816 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1817 (const_string "neon_fp_vmla_ddd")
1818 (const_string "neon_fp_vmla_qqq"))
1819 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1821 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1822 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1823 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1824 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1825 (const_string "neon_mla_qqq_8_16")
1826 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1829 (define_insn "neon_vmlal<mode>"
1830 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1831 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1832 (match_operand:VW 2 "s_register_operand" "w")
1833 (match_operand:VW 3 "s_register_operand" "w")
1834 (match_operand:SI 4 "immediate_operand" "i")]
1837 "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
1838 [(set (attr "neon_type")
1839 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1840 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1841 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1844 (define_insn "neon_vmls<mode>"
1845 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1846 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
1847 (match_operand:VDQW 2 "s_register_operand" "w")
1848 (match_operand:VDQW 3 "s_register_operand" "w")
1849 (match_operand:SI 4 "immediate_operand" "i")]
1852 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
1853 [(set (attr "neon_type")
1854 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1855 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1856 (const_string "neon_fp_vmla_ddd")
1857 (const_string "neon_fp_vmla_qqq"))
1858 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1860 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1861 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1862 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1864 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1865 (const_string "neon_mla_qqq_8_16")
1866 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1869 (define_insn "neon_vmlsl<mode>"
1870 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1871 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1872 (match_operand:VW 2 "s_register_operand" "w")
1873 (match_operand:VW 3 "s_register_operand" "w")
1874 (match_operand:SI 4 "immediate_operand" "i")]
1877 "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
1878 [(set (attr "neon_type")
1879 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1880 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1881 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1884 (define_insn "neon_vqdmulh<mode>"
1885 [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
1886 (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
1887 (match_operand:VMDQI 2 "s_register_operand" "w")
1888 (match_operand:SI 3 "immediate_operand" "i")]
1891 "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1892 [(set (attr "neon_type")
1893 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1894 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1895 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1896 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1897 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1898 (const_string "neon_mul_qqq_8_16_32_ddd_32")
1899 (const_string "neon_mul_qqq_8_16_32_ddd_32"))))]
1902 (define_insn "neon_vqdmlal<mode>"
1903 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1904 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1905 (match_operand:VMDI 2 "s_register_operand" "w")
1906 (match_operand:VMDI 3 "s_register_operand" "w")
1907 (match_operand:SI 4 "immediate_operand" "i")]
1910 "vqdmlal.<V_s_elem>\t%q0, %P2, %P3"
1911 [(set (attr "neon_type")
1912 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1913 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1914 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1917 (define_insn "neon_vqdmlsl<mode>"
1918 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1919 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1920 (match_operand:VMDI 2 "s_register_operand" "w")
1921 (match_operand:VMDI 3 "s_register_operand" "w")
1922 (match_operand:SI 4 "immediate_operand" "i")]
1925 "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3"
1926 [(set (attr "neon_type")
1927 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1928 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1929 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1932 (define_insn "neon_vmull<mode>"
1933 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1934 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
1935 (match_operand:VW 2 "s_register_operand" "w")
1936 (match_operand:SI 3 "immediate_operand" "i")]
1939 "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1940 [(set (attr "neon_type")
1941 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1942 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1943 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1946 (define_insn "neon_vqdmull<mode>"
1947 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1948 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
1949 (match_operand:VMDI 2 "s_register_operand" "w")
1950 (match_operand:SI 3 "immediate_operand" "i")]
1953 "vqdmull.<V_s_elem>\t%q0, %P1, %P2"
1954 [(set (attr "neon_type")
1955 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1956 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1957 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1960 (define_insn "neon_vsub<mode>"
1961 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1962 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1963 (match_operand:VDQX 2 "s_register_operand" "w")
1964 (match_operand:SI 3 "immediate_operand" "i")]
1967 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1968 [(set (attr "neon_type")
1969 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1970 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1971 (const_string "neon_fp_vadd_ddd_vabs_dd")
1972 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1973 (const_string "neon_int_2")))]
1976 (define_insn "neon_vsubl<mode>"
1977 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1978 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1979 (match_operand:VDI 2 "s_register_operand" "w")
1980 (match_operand:SI 3 "immediate_operand" "i")]
1983 "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1984 [(set_attr "neon_type" "neon_int_2")]
1987 (define_insn "neon_vsubw<mode>"
1988 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1989 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1990 (match_operand:VDI 2 "s_register_operand" "w")
1991 (match_operand:SI 3 "immediate_operand" "i")]
1994 "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
1995 [(set_attr "neon_type" "neon_int_2")]
1998 (define_insn "neon_vqsub<mode>"
1999 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2000 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2001 (match_operand:VDQIX 2 "s_register_operand" "w")
2002 (match_operand:SI 3 "immediate_operand" "i")]
2005 "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2006 [(set_attr "neon_type" "neon_int_5")]
2009 (define_insn "neon_vhsub<mode>"
2010 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2011 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2012 (match_operand:VDQIW 2 "s_register_operand" "w")
2013 (match_operand:SI 3 "immediate_operand" "i")]
2016 "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2017 [(set_attr "neon_type" "neon_int_5")]
2020 (define_insn "neon_vsubhn<mode>"
2021 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2022 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2023 (match_operand:VN 2 "s_register_operand" "w")
2024 (match_operand:SI 3 "immediate_operand" "i")]
2027 "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2"
2028 [(set_attr "neon_type" "neon_int_4")]
2031 (define_insn "neon_vceq<mode>"
2032 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2033 (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
2034 (match_operand:VDQW 2 "s_register_operand" "w")
2035 (match_operand:SI 3 "immediate_operand" "i")]
2038 "vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2039 [(set (attr "neon_type")
2040 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2041 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2042 (const_string "neon_fp_vadd_ddd_vabs_dd")
2043 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2044 (const_string "neon_int_5")))]
2047 (define_insn "neon_vcge<mode>"
2048 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2049 (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
2050 (match_operand:VDQW 2 "s_register_operand" "w")
2051 (match_operand:SI 3 "immediate_operand" "i")]
2054 "vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2055 [(set (attr "neon_type")
2056 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2057 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2058 (const_string "neon_fp_vadd_ddd_vabs_dd")
2059 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2060 (const_string "neon_int_5")))]
2063 (define_insn "neon_vcgt<mode>"
2064 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2065 (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
2066 (match_operand:VDQW 2 "s_register_operand" "w")
2067 (match_operand:SI 3 "immediate_operand" "i")]
2070 "vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2071 [(set (attr "neon_type")
2072 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2073 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2074 (const_string "neon_fp_vadd_ddd_vabs_dd")
2075 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2076 (const_string "neon_int_5")))]
2079 (define_insn "neon_vcage<mode>"
2080 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2081 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2082 (match_operand:VCVTF 2 "s_register_operand" "w")
2083 (match_operand:SI 3 "immediate_operand" "i")]
2086 "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2087 [(set (attr "neon_type")
2088 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2089 (const_string "neon_fp_vadd_ddd_vabs_dd")
2090 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2093 (define_insn "neon_vcagt<mode>"
2094 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2095 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2096 (match_operand:VCVTF 2 "s_register_operand" "w")
2097 (match_operand:SI 3 "immediate_operand" "i")]
2100 "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2101 [(set (attr "neon_type")
2102 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2103 (const_string "neon_fp_vadd_ddd_vabs_dd")
2104 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2107 (define_insn "neon_vtst<mode>"
2108 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2109 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2110 (match_operand:VDQIW 2 "s_register_operand" "w")
2111 (match_operand:SI 3 "immediate_operand" "i")]
2114 "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2115 [(set_attr "neon_type" "neon_int_4")]
2118 (define_insn "neon_vabd<mode>"
2119 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2120 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2121 (match_operand:VDQW 2 "s_register_operand" "w")
2122 (match_operand:SI 3 "immediate_operand" "i")]
2125 "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2126 [(set (attr "neon_type")
2127 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2128 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2129 (const_string "neon_fp_vadd_ddd_vabs_dd")
2130 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2131 (const_string "neon_int_5")))]
2134 (define_insn "neon_vabdl<mode>"
2135 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2136 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2137 (match_operand:VW 2 "s_register_operand" "w")
2138 (match_operand:SI 3 "immediate_operand" "i")]
2141 "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2142 [(set_attr "neon_type" "neon_int_5")]
2145 (define_insn "neon_vaba<mode>"
2146 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2147 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "0")
2148 (match_operand:VDQIW 2 "s_register_operand" "w")
2149 (match_operand:VDQIW 3 "s_register_operand" "w")
2150 (match_operand:SI 4 "immediate_operand" "i")]
2153 "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2154 [(set (attr "neon_type")
2155 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2156 (const_string "neon_vaba") (const_string "neon_vaba_qqq")))]
2159 (define_insn "neon_vabal<mode>"
2160 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2161 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2162 (match_operand:VW 2 "s_register_operand" "w")
2163 (match_operand:VW 3 "s_register_operand" "w")
2164 (match_operand:SI 4 "immediate_operand" "i")]
2167 "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2168 [(set_attr "neon_type" "neon_vaba")]
2171 (define_insn "neon_vmax<mode>"
2172 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2173 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2174 (match_operand:VDQW 2 "s_register_operand" "w")
2175 (match_operand:SI 3 "immediate_operand" "i")]
2178 "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2179 [(set (attr "neon_type")
2180 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2181 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2182 (const_string "neon_fp_vadd_ddd_vabs_dd")
2183 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2184 (const_string "neon_int_5")))]
2187 (define_insn "neon_vmin<mode>"
2188 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2189 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2190 (match_operand:VDQW 2 "s_register_operand" "w")
2191 (match_operand:SI 3 "immediate_operand" "i")]
2194 "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2195 [(set (attr "neon_type")
2196 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2197 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2198 (const_string "neon_fp_vadd_ddd_vabs_dd")
2199 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2200 (const_string "neon_int_5")))]
2203 (define_expand "neon_vpadd<mode>"
2204 [(match_operand:VD 0 "s_register_operand" "=w")
2205 (match_operand:VD 1 "s_register_operand" "w")
2206 (match_operand:VD 2 "s_register_operand" "w")
2207 (match_operand:SI 3 "immediate_operand" "i")]
2210 emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1],
2215 (define_insn "neon_vpaddl<mode>"
2216 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2217 (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")
2218 (match_operand:SI 2 "immediate_operand" "i")]
2221 "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2222 ;; Assume this schedules like vaddl.
2223 [(set_attr "neon_type" "neon_int_3")]
2226 (define_insn "neon_vpadal<mode>"
2227 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2228 (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0")
2229 (match_operand:VDQIW 2 "s_register_operand" "w")
2230 (match_operand:SI 3 "immediate_operand" "i")]
2233 "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
2234 ;; Assume this schedules like vpadd.
2235 [(set_attr "neon_type" "neon_int_1")]
2238 (define_insn "neon_vpmax<mode>"
2239 [(set (match_operand:VD 0 "s_register_operand" "=w")
2240 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2241 (match_operand:VD 2 "s_register_operand" "w")
2242 (match_operand:SI 3 "immediate_operand" "i")]
2245 "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2246 ;; Assume this schedules like vmax.
2247 [(set (attr "neon_type")
2248 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2249 (const_string "neon_fp_vadd_ddd_vabs_dd")
2250 (const_string "neon_int_5")))]
2253 (define_insn "neon_vpmin<mode>"
2254 [(set (match_operand:VD 0 "s_register_operand" "=w")
2255 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2256 (match_operand:VD 2 "s_register_operand" "w")
2257 (match_operand:SI 3 "immediate_operand" "i")]
2260 "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2261 ;; Assume this schedules like vmin.
2262 [(set (attr "neon_type")
2263 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2264 (const_string "neon_fp_vadd_ddd_vabs_dd")
2265 (const_string "neon_int_5")))]
2268 (define_insn "neon_vrecps<mode>"
2269 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2270 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2271 (match_operand:VCVTF 2 "s_register_operand" "w")
2272 (match_operand:SI 3 "immediate_operand" "i")]
2275 "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2276 [(set (attr "neon_type")
2277 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2278 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2279 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2282 (define_insn "neon_vrsqrts<mode>"
2283 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2284 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2285 (match_operand:VCVTF 2 "s_register_operand" "w")
2286 (match_operand:SI 3 "immediate_operand" "i")]
2289 "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2290 [(set (attr "neon_type")
2291 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2292 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2293 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2296 (define_insn "neon_vabs<mode>"
2297 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2298 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2299 (match_operand:SI 2 "immediate_operand" "i")]
2302 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2303 [(set (attr "neon_type")
2304 (if_then_else (ior (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2305 (ne (symbol_ref "<Is_float_mode>") (const_int 0)))
2307 (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2308 (const_string "neon_fp_vadd_ddd_vabs_dd")
2309 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2310 (const_string "neon_vqneg_vqabs")))]
2313 (define_insn "neon_vqabs<mode>"
2314 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2315 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2316 (match_operand:SI 2 "immediate_operand" "i")]
2319 "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2320 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2323 (define_expand "neon_vneg<mode>"
2324 [(match_operand:VDQW 0 "s_register_operand" "")
2325 (match_operand:VDQW 1 "s_register_operand" "")
2326 (match_operand:SI 2 "immediate_operand" "")]
2329 emit_insn (gen_neg<mode>2 (operands[0], operands[1]));
2333 (define_insn "neon_vqneg<mode>"
2334 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2335 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2336 (match_operand:SI 2 "immediate_operand" "i")]
2339 "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2340 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2343 (define_insn "neon_vcls<mode>"
2344 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2345 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2346 (match_operand:SI 2 "immediate_operand" "i")]
2349 "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2350 [(set_attr "neon_type" "neon_int_1")]
2353 (define_insn "neon_vclz<mode>"
2354 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2355 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2356 (match_operand:SI 2 "immediate_operand" "i")]
2359 "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1"
2360 [(set_attr "neon_type" "neon_int_1")]
2363 (define_insn "neon_vcnt<mode>"
2364 [(set (match_operand:VE 0 "s_register_operand" "=w")
2365 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
2366 (match_operand:SI 2 "immediate_operand" "i")]
2369 "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2370 [(set_attr "neon_type" "neon_int_1")]
2373 (define_insn "neon_vrecpe<mode>"
2374 [(set (match_operand:V32 0 "s_register_operand" "=w")
2375 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2376 (match_operand:SI 2 "immediate_operand" "i")]
2379 "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2380 [(set (attr "neon_type")
2381 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2382 (const_string "neon_fp_vadd_ddd_vabs_dd")
2383 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2386 (define_insn "neon_vrsqrte<mode>"
2387 [(set (match_operand:V32 0 "s_register_operand" "=w")
2388 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2389 (match_operand:SI 2 "immediate_operand" "i")]
2392 "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2393 [(set (attr "neon_type")
2394 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2395 (const_string "neon_fp_vadd_ddd_vabs_dd")
2396 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2399 (define_expand "neon_vmvn<mode>"
2400 [(match_operand:VDQIW 0 "s_register_operand" "")
2401 (match_operand:VDQIW 1 "s_register_operand" "")
2402 (match_operand:SI 2 "immediate_operand" "")]
2405 emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1]));
2409 (define_insn "neon_vget_lane<mode>_sext_internal"
2410 [(set (match_operand:SI 0 "s_register_operand" "=r")
2412 (vec_select:<V_elem>
2413 (match_operand:VD 1 "s_register_operand" "w")
2414 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2416 "vmov%?.s<V_sz_elem>\t%0, %P1[%c2]"
2417 [(set_attr "predicable" "yes")
2418 (set_attr "neon_type" "neon_bp_simple")]
2421 (define_insn "neon_vget_lane<mode>_zext_internal"
2422 [(set (match_operand:SI 0 "s_register_operand" "=r")
2424 (vec_select:<V_elem>
2425 (match_operand:VD 1 "s_register_operand" "w")
2426 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2428 "vmov%?.u<V_sz_elem>\t%0, %P1[%c2]"
2429 [(set_attr "predicable" "yes")
2430 (set_attr "neon_type" "neon_bp_simple")]
2433 (define_insn "neon_vget_lane<mode>_sext_internal"
2434 [(set (match_operand:SI 0 "s_register_operand" "=r")
2436 (vec_select:<V_elem>
2437 (match_operand:VQ 1 "s_register_operand" "w")
2438 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2442 int regno = REGNO (operands[1]);
2443 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2444 unsigned int elt = INTVAL (operands[2]);
2446 ops[0] = operands[0];
2447 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2448 ops[2] = GEN_INT (elt % halfelts);
2449 output_asm_insn ("vmov%?.s<V_sz_elem>\t%0, %P1[%c2]", ops);
2453 [(set_attr "predicable" "yes")
2454 (set_attr "neon_type" "neon_bp_simple")]
2457 (define_insn "neon_vget_lane<mode>_zext_internal"
2458 [(set (match_operand:SI 0 "s_register_operand" "=r")
2460 (vec_select:<V_elem>
2461 (match_operand:VQ 1 "s_register_operand" "w")
2462 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2466 int regno = REGNO (operands[1]);
2467 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2468 unsigned int elt = INTVAL (operands[2]);
2470 ops[0] = operands[0];
2471 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2472 ops[2] = GEN_INT (elt % halfelts);
2473 output_asm_insn ("vmov%?.u<V_sz_elem>\t%0, %P1[%c2]", ops);
2477 [(set_attr "predicable" "yes")
2478 (set_attr "neon_type" "neon_bp_simple")]
2481 (define_expand "neon_vget_lane<mode>"
2482 [(match_operand:<V_ext> 0 "s_register_operand" "")
2483 (match_operand:VDQW 1 "s_register_operand" "")
2484 (match_operand:SI 2 "immediate_operand" "")
2485 (match_operand:SI 3 "immediate_operand" "")]
2488 HOST_WIDE_INT magic = INTVAL (operands[3]);
2491 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode));
2493 if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32)
2494 insn = gen_vec_extract<mode> (operands[0], operands[1], operands[2]);
2497 if ((magic & 1) != 0)
2498 insn = gen_neon_vget_lane<mode>_sext_internal (operands[0], operands[1],
2501 insn = gen_neon_vget_lane<mode>_zext_internal (operands[0], operands[1],
2508 ; Operand 3 (info word) is ignored because it does nothing useful with 64-bit
2511 (define_insn "neon_vget_lanedi"
2512 [(set (match_operand:DI 0 "s_register_operand" "=r")
2513 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
2514 (match_operand:SI 2 "immediate_operand" "i")
2515 (match_operand:SI 3 "immediate_operand" "i")]
2519 neon_lane_bounds (operands[2], 0, 1);
2520 return "vmov%?\t%Q0, %R0, %P1 @ di";
2522 [(set_attr "predicable" "yes")
2523 (set_attr "neon_type" "neon_bp_simple")]
2526 (define_insn "neon_vget_lanev2di"
2527 [(set (match_operand:DI 0 "s_register_operand" "=r")
2528 (unspec:DI [(match_operand:V2DI 1 "s_register_operand" "w")
2529 (match_operand:SI 2 "immediate_operand" "i")
2530 (match_operand:SI 3 "immediate_operand" "i")]
2535 unsigned int regno = REGNO (operands[1]);
2536 unsigned int elt = INTVAL (operands[2]);
2538 neon_lane_bounds (operands[2], 0, 2);
2540 ops[0] = operands[0];
2541 ops[1] = gen_rtx_REG (DImode, regno + 2 * elt);
2542 output_asm_insn ("vmov%?\t%Q0, %R0, %P1 @ v2di", ops);
2546 [(set_attr "predicable" "yes")
2547 (set_attr "neon_type" "neon_bp_simple")]
2550 (define_insn "neon_vset_lane<mode>"
2551 [(set (match_operand:VD 0 "s_register_operand" "=w")
2552 (unspec:VD [(match_operand:<V_elem> 1 "s_register_operand" "r")
2553 (match_operand:VD 2 "s_register_operand" "0")
2554 (match_operand:SI 3 "immediate_operand" "i")]
2558 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
2559 return "vmov%?.<V_sz_elem>\t%P0[%c3], %1";
2561 [(set_attr "predicable" "yes")
2562 (set_attr "neon_type" "neon_bp_simple")]
2565 ; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
2567 (define_insn "neon_vset_lanedi"
2568 [(set (match_operand:DI 0 "s_register_operand" "=w")
2569 (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")
2570 (match_operand:DI 2 "s_register_operand" "0")
2571 (match_operand:SI 3 "immediate_operand" "i")]
2575 neon_lane_bounds (operands[3], 0, 1);
2576 return "vmov%?\t%P0, %Q1, %R1 @ di";
2578 [(set_attr "predicable" "yes")
2579 (set_attr "neon_type" "neon_bp_simple")]
2582 (define_insn "neon_vset_lane<mode>"
2583 [(set (match_operand:VQ 0 "s_register_operand" "=w")
2584 (unspec:VQ [(match_operand:<V_elem> 1 "s_register_operand" "r")
2585 (match_operand:VQ 2 "s_register_operand" "0")
2586 (match_operand:SI 3 "immediate_operand" "i")]
2591 unsigned int regno = REGNO (operands[0]);
2592 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2593 unsigned int elt = INTVAL (operands[3]);
2595 neon_lane_bounds (operands[3], 0, halfelts * 2);
2597 ops[0] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2598 ops[1] = operands[1];
2599 ops[2] = GEN_INT (elt % halfelts);
2600 output_asm_insn ("vmov%?.<V_sz_elem>\t%P0[%c2], %1", ops);
2604 [(set_attr "predicable" "yes")
2605 (set_attr "neon_type" "neon_bp_simple")]
2608 (define_insn "neon_vset_lanev2di"
2609 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2610 (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "r")
2611 (match_operand:V2DI 2 "s_register_operand" "0")
2612 (match_operand:SI 3 "immediate_operand" "i")]
2617 unsigned int regno = REGNO (operands[0]);
2618 unsigned int elt = INTVAL (operands[3]);
2620 neon_lane_bounds (operands[3], 0, 2);
2622 ops[0] = gen_rtx_REG (DImode, regno + 2 * elt);
2623 ops[1] = operands[1];
2624 output_asm_insn ("vmov%?\t%P0, %Q1, %R1 @ v2di", ops);
2628 [(set_attr "predicable" "yes")
2629 (set_attr "neon_type" "neon_bp_simple")]
2632 (define_expand "neon_vcreate<mode>"
2633 [(match_operand:VDX 0 "s_register_operand" "")
2634 (match_operand:DI 1 "general_operand" "")]
2637 rtx src = gen_lowpart (<MODE>mode, operands[1]);
2638 emit_move_insn (operands[0], src);
2642 (define_insn "neon_vdup_n<mode>"
2643 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2644 (unspec:VDQW [(match_operand:<V_elem> 1 "s_register_operand" "r")]
2647 "vdup%?.<V_sz_elem>\t%<V_reg>0, %1"
2648 ;; Assume this schedules like vmov.
2649 [(set_attr "predicable" "yes")
2650 (set_attr "neon_type" "neon_bp_simple")]
2653 (define_insn "neon_vdup_ndi"
2654 [(set (match_operand:DI 0 "s_register_operand" "=w")
2655 (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")]
2658 "vmov%?\t%P0, %Q1, %R1"
2659 [(set_attr "predicable" "yes")
2660 (set_attr "neon_type" "neon_bp_simple")]
2663 (define_insn "neon_vdup_nv2di"
2664 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2665 (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "r")]
2668 "vmov%?\t%e0, %Q1, %R1\;vmov%?\t%f0, %Q1, %R1"
2669 [(set_attr "predicable" "yes")
2670 (set_attr "length" "8")
2671 (set_attr "neon_type" "neon_bp_simple")]
2674 (define_insn "neon_vdup_lane<mode>"
2675 [(set (match_operand:VD 0 "s_register_operand" "=w")
2676 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2677 (match_operand:SI 2 "immediate_operand" "i")]
2681 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode));
2682 return "vdup.<V_sz_elem>\t%P0, %P1[%c2]";
2684 ;; Assume this schedules like vmov.
2685 [(set_attr "neon_type" "neon_bp_simple")]
2688 (define_insn "neon_vdup_lane<mode>"
2689 [(set (match_operand:VQ 0 "s_register_operand" "=w")
2690 (unspec:VQ [(match_operand:<V_HALF> 1 "s_register_operand" "w")
2691 (match_operand:SI 2 "immediate_operand" "i")]
2695 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<V_HALF>mode));
2696 return "vdup.<V_sz_elem>\t%q0, %P1[%c2]";
2698 ;; Assume this schedules like vmov.
2699 [(set_attr "neon_type" "neon_bp_simple")]
2702 ; Scalar index is ignored, since only zero is valid here.
2703 (define_expand "neon_vdup_lanedi"
2704 [(set (match_operand:DI 0 "s_register_operand" "=w")
2705 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
2706 (match_operand:SI 2 "immediate_operand" "i")]
2710 neon_lane_bounds (operands[2], 0, 1);
2711 emit_move_insn (operands[0], operands[1]);
2716 (define_insn "neon_vdup_lanev2di"
2717 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2718 (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "w")
2719 (match_operand:SI 2 "immediate_operand" "i")]
2723 neon_lane_bounds (operands[2], 0, 1);
2724 return "vmov\t%e0, %P1\;vmov\t%f0, %P1";
2726 [(set_attr "length" "8")
2727 (set_attr "neon_type" "neon_bp_simple")]
2730 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
2732 ;; FIXME: A different implementation of this builtin could make it much
2733 ;; more likely that we wouldn't actually need to output anything (we could make
2734 ;; it so that the reg allocator puts things in the right places magically
2735 ;; instead). Lack of subregs for vectors makes that tricky though, I think.
2737 (define_insn "neon_vcombine<mode>"
2738 [(set (match_operand:<V_DOUBLE> 0 "s_register_operand" "=w")
2739 (unspec:<V_DOUBLE> [(match_operand:VDX 1 "s_register_operand" "w")
2740 (match_operand:VDX 2 "s_register_operand" "w")]
2744 int dest = REGNO (operands[0]);
2745 int src1 = REGNO (operands[1]);
2746 int src2 = REGNO (operands[2]);
2749 if (src1 == dest && src2 == dest + 2)
2751 else if (src2 == dest && src1 == dest + 2)
2752 /* Special case of reversed high/low parts. */
2753 return "vswp\t%P1, %P2";
2755 destlo = gen_rtx_REG (<MODE>mode, dest);
2757 if (!reg_overlap_mentioned_p (operands[2], destlo))
2759 /* Try to avoid unnecessary moves if part of the result is in the right
2762 output_asm_insn ("vmov\t%e0, %P1", operands);
2763 if (src2 != dest + 2)
2764 output_asm_insn ("vmov\t%f0, %P2", operands);
2768 if (src2 != dest + 2)
2769 output_asm_insn ("vmov\t%f0, %P2", operands);
2771 output_asm_insn ("vmov\t%e0, %P1", operands);
2776 ;; We set the neon_type attribute based on the vmov instructions above.
2777 [(set_attr "length" "8")
2778 (set_attr "neon_type" "neon_bp_simple")]
2781 (define_insn "neon_vget_high<mode>"
2782 [(set (match_operand:<V_HALF> 0 "s_register_operand" "=w")
2783 (unspec:<V_HALF> [(match_operand:VQX 1 "s_register_operand" "w")]
2787 int dest = REGNO (operands[0]);
2788 int src = REGNO (operands[1]);
2790 if (dest != src + 2)
2791 return "vmov\t%P0, %f1";
2795 [(set_attr "neon_type" "neon_bp_simple")]
2798 (define_insn "neon_vget_low<mode>"
2799 [(set (match_operand:<V_HALF> 0 "s_register_operand" "=w")
2800 (unspec:<V_HALF> [(match_operand:VQX 1 "s_register_operand" "w")]
2804 int dest = REGNO (operands[0]);
2805 int src = REGNO (operands[1]);
2808 return "vmov\t%P0, %e1";
2812 [(set_attr "neon_type" "neon_bp_simple")]
2815 (define_insn "neon_vcvt<mode>"
2816 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2817 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
2818 (match_operand:SI 2 "immediate_operand" "i")]
2821 "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1"
2822 [(set (attr "neon_type")
2823 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2824 (const_string "neon_fp_vadd_ddd_vabs_dd")
2825 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2828 (define_insn "neon_vcvt<mode>"
2829 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2830 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
2831 (match_operand:SI 2 "immediate_operand" "i")]
2834 "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1"
2835 [(set (attr "neon_type")
2836 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2837 (const_string "neon_fp_vadd_ddd_vabs_dd")
2838 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2841 (define_insn "neon_vcvt_n<mode>"
2842 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2843 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
2844 (match_operand:SI 2 "immediate_operand" "i")
2845 (match_operand:SI 3 "immediate_operand" "i")]
2849 neon_const_bounds (operands[2], 1, 33);
2850 return "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2";
2852 [(set (attr "neon_type")
2853 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2854 (const_string "neon_fp_vadd_ddd_vabs_dd")
2855 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2858 (define_insn "neon_vcvt_n<mode>"
2859 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2860 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
2861 (match_operand:SI 2 "immediate_operand" "i")
2862 (match_operand:SI 3 "immediate_operand" "i")]
2866 neon_const_bounds (operands[2], 1, 33);
2867 return "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2";
2869 [(set (attr "neon_type")
2870 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2871 (const_string "neon_fp_vadd_ddd_vabs_dd")
2872 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2875 (define_insn "neon_vmovn<mode>"
2876 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2877 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2878 (match_operand:SI 2 "immediate_operand" "i")]
2881 "vmovn.<V_if_elem>\t%P0, %q1"
2882 [(set_attr "neon_type" "neon_bp_simple")]
2885 (define_insn "neon_vqmovn<mode>"
2886 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2887 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2888 (match_operand:SI 2 "immediate_operand" "i")]
2891 "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1"
2892 [(set_attr "neon_type" "neon_shift_2")]
2895 (define_insn "neon_vqmovun<mode>"
2896 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2897 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2898 (match_operand:SI 2 "immediate_operand" "i")]
2901 "vqmovun.<V_s_elem>\t%P0, %q1"
2902 [(set_attr "neon_type" "neon_shift_2")]
2905 (define_insn "neon_vmovl<mode>"
2906 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2907 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2908 (match_operand:SI 2 "immediate_operand" "i")]
2911 "vmovl.%T2%#<V_sz_elem>\t%q0, %P1"
2912 [(set_attr "neon_type" "neon_shift_1")]
2915 (define_insn "neon_vmul_lane<mode>"
2916 [(set (match_operand:VMD 0 "s_register_operand" "=w")
2917 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
2918 (match_operand:VMD 2 "s_register_operand"
2919 "<scalar_mul_constraint>")
2920 (match_operand:SI 3 "immediate_operand" "i")
2921 (match_operand:SI 4 "immediate_operand" "i")]
2925 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
2926 return "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]";
2928 [(set (attr "neon_type")
2929 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2930 (const_string "neon_fp_vmul_ddd")
2931 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2932 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
2933 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))))]
2936 (define_insn "neon_vmul_lane<mode>"
2937 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
2938 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
2939 (match_operand:<V_HALF> 2 "s_register_operand"
2940 "<scalar_mul_constraint>")
2941 (match_operand:SI 3 "immediate_operand" "i")
2942 (match_operand:SI 4 "immediate_operand" "i")]
2946 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<V_HALF>mode));
2947 return "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]";
2949 [(set (attr "neon_type")
2950 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2951 (const_string "neon_fp_vmul_qqd")
2952 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2953 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
2954 (const_string "neon_mul_qqd_32_scalar"))))]
2957 (define_insn "neon_vmull_lane<mode>"
2958 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2959 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
2960 (match_operand:VMDI 2 "s_register_operand"
2961 "<scalar_mul_constraint>")
2962 (match_operand:SI 3 "immediate_operand" "i")
2963 (match_operand:SI 4 "immediate_operand" "i")]
2964 UNSPEC_VMULL_LANE))]
2967 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
2968 return "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]";
2970 [(set (attr "neon_type")
2971 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2972 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
2973 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2976 (define_insn "neon_vqdmull_lane<mode>"
2977 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2978 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
2979 (match_operand:VMDI 2 "s_register_operand"
2980 "<scalar_mul_constraint>")
2981 (match_operand:SI 3 "immediate_operand" "i")
2982 (match_operand:SI 4 "immediate_operand" "i")]
2983 UNSPEC_VQDMULL_LANE))]
2986 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
2987 return "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]";
2989 [(set (attr "neon_type")
2990 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2991 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
2992 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2995 (define_insn "neon_vqdmulh_lane<mode>"
2996 [(set (match_operand:VMQI 0 "s_register_operand" "=w")
2997 (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
2998 (match_operand:<V_HALF> 2 "s_register_operand"
2999 "<scalar_mul_constraint>")
3000 (match_operand:SI 3 "immediate_operand" "i")
3001 (match_operand:SI 4 "immediate_operand" "i")]
3002 UNSPEC_VQDMULH_LANE))]
3005 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3006 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]";
3008 [(set (attr "neon_type")
3009 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3010 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3011 (const_string "neon_mul_qqd_32_scalar")))]
3014 (define_insn "neon_vqdmulh_lane<mode>"
3015 [(set (match_operand:VMDI 0 "s_register_operand" "=w")
3016 (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
3017 (match_operand:VMDI 2 "s_register_operand"
3018 "<scalar_mul_constraint>")
3019 (match_operand:SI 3 "immediate_operand" "i")
3020 (match_operand:SI 4 "immediate_operand" "i")]
3021 UNSPEC_VQDMULH_LANE))]
3024 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3025 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]";
3027 [(set (attr "neon_type")
3028 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3029 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3030 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3033 (define_insn "neon_vmla_lane<mode>"
3034 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3035 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3036 (match_operand:VMD 2 "s_register_operand" "w")
3037 (match_operand:VMD 3 "s_register_operand"
3038 "<scalar_mul_constraint>")
3039 (match_operand:SI 4 "immediate_operand" "i")
3040 (match_operand:SI 5 "immediate_operand" "i")]
3044 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3045 return "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3047 [(set (attr "neon_type")
3048 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3049 (const_string "neon_fp_vmla_ddd_scalar")
3050 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3051 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3052 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3055 (define_insn "neon_vmla_lane<mode>"
3056 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3057 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3058 (match_operand:VMQ 2 "s_register_operand" "w")
3059 (match_operand:<V_HALF> 3 "s_register_operand"
3060 "<scalar_mul_constraint>")
3061 (match_operand:SI 4 "immediate_operand" "i")
3062 (match_operand:SI 5 "immediate_operand" "i")]
3066 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3067 return "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3069 [(set (attr "neon_type")
3070 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3071 (const_string "neon_fp_vmla_qqq_scalar")
3072 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3073 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3074 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3077 (define_insn "neon_vmlal_lane<mode>"
3078 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3079 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3080 (match_operand:VMDI 2 "s_register_operand" "w")
3081 (match_operand:VMDI 3 "s_register_operand"
3082 "<scalar_mul_constraint>")
3083 (match_operand:SI 4 "immediate_operand" "i")
3084 (match_operand:SI 5 "immediate_operand" "i")]
3085 UNSPEC_VMLAL_LANE))]
3088 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3089 return "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3091 [(set (attr "neon_type")
3092 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3093 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3094 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3097 (define_insn "neon_vqdmlal_lane<mode>"
3098 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3099 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3100 (match_operand:VMDI 2 "s_register_operand" "w")
3101 (match_operand:VMDI 3 "s_register_operand"
3102 "<scalar_mul_constraint>")
3103 (match_operand:SI 4 "immediate_operand" "i")
3104 (match_operand:SI 5 "immediate_operand" "i")]
3105 UNSPEC_VQDMLAL_LANE))]
3108 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3109 return "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3111 [(set (attr "neon_type")
3112 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3113 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3114 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3117 (define_insn "neon_vmls_lane<mode>"
3118 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3119 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3120 (match_operand:VMD 2 "s_register_operand" "w")
3121 (match_operand:VMD 3 "s_register_operand"
3122 "<scalar_mul_constraint>")
3123 (match_operand:SI 4 "immediate_operand" "i")
3124 (match_operand:SI 5 "immediate_operand" "i")]
3128 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3129 return "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3131 [(set (attr "neon_type")
3132 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3133 (const_string "neon_fp_vmla_ddd_scalar")
3134 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3135 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3136 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3139 (define_insn "neon_vmls_lane<mode>"
3140 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3141 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3142 (match_operand:VMQ 2 "s_register_operand" "w")
3143 (match_operand:<V_HALF> 3 "s_register_operand"
3144 "<scalar_mul_constraint>")
3145 (match_operand:SI 4 "immediate_operand" "i")
3146 (match_operand:SI 5 "immediate_operand" "i")]
3150 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3151 return "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3153 [(set (attr "neon_type")
3154 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3155 (const_string "neon_fp_vmla_qqq_scalar")
3156 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3157 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3158 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3161 (define_insn "neon_vmlsl_lane<mode>"
3162 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3163 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3164 (match_operand:VMDI 2 "s_register_operand" "w")
3165 (match_operand:VMDI 3 "s_register_operand"
3166 "<scalar_mul_constraint>")
3167 (match_operand:SI 4 "immediate_operand" "i")
3168 (match_operand:SI 5 "immediate_operand" "i")]
3169 UNSPEC_VMLSL_LANE))]
3172 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3173 return "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3175 [(set (attr "neon_type")
3176 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3177 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3178 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3181 (define_insn "neon_vqdmlsl_lane<mode>"
3182 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3183 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3184 (match_operand:VMDI 2 "s_register_operand" "w")
3185 (match_operand:VMDI 3 "s_register_operand"
3186 "<scalar_mul_constraint>")
3187 (match_operand:SI 4 "immediate_operand" "i")
3188 (match_operand:SI 5 "immediate_operand" "i")]
3189 UNSPEC_VQDMLSL_LANE))]
3192 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3193 return "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3195 [(set (attr "neon_type")
3196 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3197 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3198 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3201 ; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
3202 ; core register into a temp register, then use a scalar taken from that. This
3203 ; isn't an optimal solution if e.g. the scalar has just been read from memory
3204 ; or extracted from another vector. The latter case it's currently better to
3205 ; use the "_lane" variant, and the former case can probably be implemented
3206 ; using vld1_lane, but that hasn't been done yet.
3208 (define_expand "neon_vmul_n<mode>"
3209 [(match_operand:VMD 0 "s_register_operand" "")
3210 (match_operand:VMD 1 "s_register_operand" "")
3211 (match_operand:<V_elem> 2 "s_register_operand" "")
3212 (match_operand:SI 3 "immediate_operand" "")]
3215 rtx tmp = gen_reg_rtx (<MODE>mode);
3216 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3217 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3218 const0_rtx, const0_rtx));
3222 (define_expand "neon_vmul_n<mode>"
3223 [(match_operand:VMQ 0 "s_register_operand" "")
3224 (match_operand:VMQ 1 "s_register_operand" "")
3225 (match_operand:<V_elem> 2 "s_register_operand" "")
3226 (match_operand:SI 3 "immediate_operand" "")]
3229 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3230 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3231 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3232 const0_rtx, const0_rtx));
3236 (define_expand "neon_vmull_n<mode>"
3237 [(match_operand:<V_widen> 0 "s_register_operand" "")
3238 (match_operand:VMDI 1 "s_register_operand" "")
3239 (match_operand:<V_elem> 2 "s_register_operand" "")
3240 (match_operand:SI 3 "immediate_operand" "")]
3243 rtx tmp = gen_reg_rtx (<MODE>mode);
3244 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3245 emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp,
3246 const0_rtx, operands[3]));
3250 (define_expand "neon_vqdmull_n<mode>"
3251 [(match_operand:<V_widen> 0 "s_register_operand" "")
3252 (match_operand:VMDI 1 "s_register_operand" "")
3253 (match_operand:<V_elem> 2 "s_register_operand" "")
3254 (match_operand:SI 3 "immediate_operand" "")]
3257 rtx tmp = gen_reg_rtx (<MODE>mode);
3258 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3259 emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp,
3260 const0_rtx, const0_rtx));
3264 (define_expand "neon_vqdmulh_n<mode>"
3265 [(match_operand:VMDI 0 "s_register_operand" "")
3266 (match_operand:VMDI 1 "s_register_operand" "")
3267 (match_operand:<V_elem> 2 "s_register_operand" "")
3268 (match_operand:SI 3 "immediate_operand" "")]
3271 rtx tmp = gen_reg_rtx (<MODE>mode);
3272 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3273 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3274 const0_rtx, operands[3]));
3278 (define_expand "neon_vqdmulh_n<mode>"
3279 [(match_operand:VMQI 0 "s_register_operand" "")
3280 (match_operand:VMQI 1 "s_register_operand" "")
3281 (match_operand:<V_elem> 2 "s_register_operand" "")
3282 (match_operand:SI 3 "immediate_operand" "")]
3285 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3286 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3287 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3288 const0_rtx, operands[3]));
3292 (define_expand "neon_vmla_n<mode>"
3293 [(match_operand:VMD 0 "s_register_operand" "")
3294 (match_operand:VMD 1 "s_register_operand" "")
3295 (match_operand:VMD 2 "s_register_operand" "")
3296 (match_operand:<V_elem> 3 "s_register_operand" "")
3297 (match_operand:SI 4 "immediate_operand" "")]
3300 rtx tmp = gen_reg_rtx (<MODE>mode);
3301 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3302 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3303 tmp, const0_rtx, operands[4]));
3307 (define_expand "neon_vmla_n<mode>"
3308 [(match_operand:VMQ 0 "s_register_operand" "")
3309 (match_operand:VMQ 1 "s_register_operand" "")
3310 (match_operand:VMQ 2 "s_register_operand" "")
3311 (match_operand:<V_elem> 3 "s_register_operand" "")
3312 (match_operand:SI 4 "immediate_operand" "")]
3315 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3316 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3317 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3318 tmp, const0_rtx, operands[4]));
3322 (define_expand "neon_vmlal_n<mode>"
3323 [(match_operand:<V_widen> 0 "s_register_operand" "")
3324 (match_operand:<V_widen> 1 "s_register_operand" "")
3325 (match_operand:VMDI 2 "s_register_operand" "")
3326 (match_operand:<V_elem> 3 "s_register_operand" "")
3327 (match_operand:SI 4 "immediate_operand" "")]
3330 rtx tmp = gen_reg_rtx (<MODE>mode);
3331 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3332 emit_insn (gen_neon_vmlal_lane<mode> (operands[0], operands[1], operands[2],
3333 tmp, const0_rtx, operands[4]));
3337 (define_expand "neon_vqdmlal_n<mode>"
3338 [(match_operand:<V_widen> 0 "s_register_operand" "")
3339 (match_operand:<V_widen> 1 "s_register_operand" "")
3340 (match_operand:VMDI 2 "s_register_operand" "")
3341 (match_operand:<V_elem> 3 "s_register_operand" "")
3342 (match_operand:SI 4 "immediate_operand" "")]
3345 rtx tmp = gen_reg_rtx (<MODE>mode);
3346 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3347 emit_insn (gen_neon_vqdmlal_lane<mode> (operands[0], operands[1], operands[2],
3348 tmp, const0_rtx, operands[4]));
3352 (define_expand "neon_vmls_n<mode>"
3353 [(match_operand:VMD 0 "s_register_operand" "")
3354 (match_operand:VMD 1 "s_register_operand" "")
3355 (match_operand:VMD 2 "s_register_operand" "")
3356 (match_operand:<V_elem> 3 "s_register_operand" "")
3357 (match_operand:SI 4 "immediate_operand" "")]
3360 rtx tmp = gen_reg_rtx (<MODE>mode);
3361 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3362 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3363 tmp, const0_rtx, operands[4]));
3367 (define_expand "neon_vmls_n<mode>"
3368 [(match_operand:VMQ 0 "s_register_operand" "")
3369 (match_operand:VMQ 1 "s_register_operand" "")
3370 (match_operand:VMQ 2 "s_register_operand" "")
3371 (match_operand:<V_elem> 3 "s_register_operand" "")
3372 (match_operand:SI 4 "immediate_operand" "")]
3375 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3376 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3377 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3378 tmp, const0_rtx, operands[4]));
3382 (define_expand "neon_vmlsl_n<mode>"
3383 [(match_operand:<V_widen> 0 "s_register_operand" "")
3384 (match_operand:<V_widen> 1 "s_register_operand" "")
3385 (match_operand:VMDI 2 "s_register_operand" "")
3386 (match_operand:<V_elem> 3 "s_register_operand" "")
3387 (match_operand:SI 4 "immediate_operand" "")]
3390 rtx tmp = gen_reg_rtx (<MODE>mode);
3391 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3392 emit_insn (gen_neon_vmlsl_lane<mode> (operands[0], operands[1], operands[2],
3393 tmp, const0_rtx, operands[4]));
3397 (define_expand "neon_vqdmlsl_n<mode>"
3398 [(match_operand:<V_widen> 0 "s_register_operand" "")
3399 (match_operand:<V_widen> 1 "s_register_operand" "")
3400 (match_operand:VMDI 2 "s_register_operand" "")
3401 (match_operand:<V_elem> 3 "s_register_operand" "")
3402 (match_operand:SI 4 "immediate_operand" "")]
3405 rtx tmp = gen_reg_rtx (<MODE>mode);
3406 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3407 emit_insn (gen_neon_vqdmlsl_lane<mode> (operands[0], operands[1], operands[2],
3408 tmp, const0_rtx, operands[4]));
3412 (define_insn "neon_vext<mode>"
3413 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
3414 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
3415 (match_operand:VDQX 2 "s_register_operand" "w")
3416 (match_operand:SI 3 "immediate_operand" "i")]
3420 neon_const_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3421 return "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3";
3423 [(set (attr "neon_type")
3424 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3425 (const_string "neon_bp_simple")
3426 (const_string "neon_bp_2cycle")))]
3429 (define_insn "neon_vrev64<mode>"
3430 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
3431 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
3432 (match_operand:SI 2 "immediate_operand" "i")]
3435 "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3436 [(set_attr "neon_type" "neon_bp_simple")]
3439 (define_insn "neon_vrev32<mode>"
3440 [(set (match_operand:VX 0 "s_register_operand" "=w")
3441 (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")
3442 (match_operand:SI 2 "immediate_operand" "i")]
3445 "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3446 [(set_attr "neon_type" "neon_bp_simple")]
3449 (define_insn "neon_vrev16<mode>"
3450 [(set (match_operand:VE 0 "s_register_operand" "=w")
3451 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
3452 (match_operand:SI 2 "immediate_operand" "i")]
3455 "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3456 [(set_attr "neon_type" "neon_bp_simple")]
3459 ; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
3460 ; allocation. For an intrinsic of form:
3461 ; rD = vbsl_* (rS, rN, rM)
3462 ; We can use any of:
3463 ; vbsl rS, rN, rM (if D = S)
3464 ; vbit rD, rN, rS (if D = M, so 1-bits in rS choose bits from rN, else rM)
3465 ; vbif rD, rM, rS (if D = N, so 0-bits in rS choose bits from rM, else rN)
3467 (define_insn "neon_vbsl<mode>_internal"
3468 [(set (match_operand:VDQX 0 "s_register_operand" "=w,w,w")
3469 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" " 0,w,w")
3470 (match_operand:VDQX 2 "s_register_operand" " w,w,0")
3471 (match_operand:VDQX 3 "s_register_operand" " w,0,w")]
3475 vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3
3476 vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1
3477 vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1"
3478 [(set_attr "neon_type" "neon_int_1")]
3481 (define_expand "neon_vbsl<mode>"
3482 [(set (match_operand:VDQX 0 "s_register_operand" "")
3483 (unspec:VDQX [(match_operand:<V_cmp_result> 1 "s_register_operand" "")
3484 (match_operand:VDQX 2 "s_register_operand" "")
3485 (match_operand:VDQX 3 "s_register_operand" "")]
3489 /* We can't alias operands together if they have different modes. */
3490 operands[1] = gen_lowpart (<MODE>mode, operands[1]);
3493 (define_insn "neon_vshl<mode>"
3494 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3495 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3496 (match_operand:VDQIX 2 "s_register_operand" "w")
3497 (match_operand:SI 3 "immediate_operand" "i")]
3500 "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3501 [(set (attr "neon_type")
3502 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3503 (const_string "neon_vshl_ddd")
3504 (const_string "neon_shift_3")))]
3507 (define_insn "neon_vqshl<mode>"
3508 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3509 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3510 (match_operand:VDQIX 2 "s_register_operand" "w")
3511 (match_operand:SI 3 "immediate_operand" "i")]
3514 "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3515 [(set (attr "neon_type")
3516 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3517 (const_string "neon_shift_2")
3518 (const_string "neon_vqshl_vrshl_vqrshl_qqq")))]
3521 (define_insn "neon_vshr_n<mode>"
3522 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3523 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3524 (match_operand:SI 2 "immediate_operand" "i")
3525 (match_operand:SI 3 "immediate_operand" "i")]
3529 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) + 1);
3530 return "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3532 [(set_attr "neon_type" "neon_shift_1")]
3535 (define_insn "neon_vshrn_n<mode>"
3536 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3537 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3538 (match_operand:SI 2 "immediate_operand" "i")
3539 (match_operand:SI 3 "immediate_operand" "i")]
3543 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3544 return "v%O3shrn.<V_if_elem>\t%P0, %q1, %2";
3546 [(set_attr "neon_type" "neon_shift_1")]
3549 (define_insn "neon_vqshrn_n<mode>"
3550 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3551 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3552 (match_operand:SI 2 "immediate_operand" "i")
3553 (match_operand:SI 3 "immediate_operand" "i")]
3557 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3558 return "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3560 [(set_attr "neon_type" "neon_shift_2")]
3563 (define_insn "neon_vqshrun_n<mode>"
3564 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3565 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3566 (match_operand:SI 2 "immediate_operand" "i")
3567 (match_operand:SI 3 "immediate_operand" "i")]
3571 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3572 return "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3574 [(set_attr "neon_type" "neon_shift_2")]
3577 (define_insn "neon_vshl_n<mode>"
3578 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3579 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3580 (match_operand:SI 2 "immediate_operand" "i")
3581 (match_operand:SI 3 "immediate_operand" "i")]
3585 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3586 return "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2";
3588 [(set_attr "neon_type" "neon_shift_1")]
3591 (define_insn "neon_vqshl_n<mode>"
3592 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3593 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3594 (match_operand:SI 2 "immediate_operand" "i")
3595 (match_operand:SI 3 "immediate_operand" "i")]
3599 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3600 return "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3602 [(set_attr "neon_type" "neon_shift_2")]
3605 (define_insn "neon_vqshlu_n<mode>"
3606 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3607 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3608 (match_operand:SI 2 "immediate_operand" "i")
3609 (match_operand:SI 3 "immediate_operand" "i")]
3613 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3614 return "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3616 [(set_attr "neon_type" "neon_shift_2")]
3619 (define_insn "neon_vshll_n<mode>"
3620 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3621 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
3622 (match_operand:SI 2 "immediate_operand" "i")
3623 (match_operand:SI 3 "immediate_operand" "i")]
3627 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3628 return "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2";
3630 [(set_attr "neon_type" "neon_shift_1")]
3633 (define_insn "neon_vsra_n<mode>"
3634 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3635 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3636 (match_operand:VDQIX 2 "s_register_operand" "w")
3637 (match_operand:SI 3 "immediate_operand" "i")
3638 (match_operand:SI 4 "immediate_operand" "i")]
3642 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
3643 return "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3645 [(set_attr "neon_type" "neon_vsra_vrsra")]
3648 (define_insn "neon_vsri_n<mode>"
3649 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3650 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3651 (match_operand:VDQIX 2 "s_register_operand" "w")
3652 (match_operand:SI 3 "immediate_operand" "i")]
3656 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
3657 return "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3659 [(set (attr "neon_type")
3660 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3661 (const_string "neon_shift_1")
3662 (const_string "neon_shift_3")))]
3665 (define_insn "neon_vsli_n<mode>"
3666 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3667 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3668 (match_operand:VDQIX 2 "s_register_operand" "w")
3669 (match_operand:SI 3 "immediate_operand" "i")]
3673 neon_const_bounds (operands[3], 0, neon_element_bits (<MODE>mode));
3674 return "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3676 [(set (attr "neon_type")
3677 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3678 (const_string "neon_shift_1")
3679 (const_string "neon_shift_3")))]
3682 (define_insn "neon_vtbl1v8qi"
3683 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3684 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")
3685 (match_operand:V8QI 2 "s_register_operand" "w")]
3688 "vtbl.8\t%P0, {%P1}, %P2"
3689 [(set_attr "neon_type" "neon_bp_2cycle")]
3692 (define_insn "neon_vtbl2v8qi"
3693 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3694 (unspec:V8QI [(match_operand:TI 1 "s_register_operand" "w")
3695 (match_operand:V8QI 2 "s_register_operand" "w")]
3700 int tabbase = REGNO (operands[1]);
3702 ops[0] = operands[0];
3703 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3704 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3705 ops[3] = operands[2];
3706 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2}, %P3", ops);
3710 [(set_attr "neon_type" "neon_bp_2cycle")]
3713 (define_insn "neon_vtbl3v8qi"
3714 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3715 (unspec:V8QI [(match_operand:EI 1 "s_register_operand" "w")
3716 (match_operand:V8QI 2 "s_register_operand" "w")]
3721 int tabbase = REGNO (operands[1]);
3723 ops[0] = operands[0];
3724 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3725 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3726 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3727 ops[4] = operands[2];
3728 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
3732 [(set_attr "neon_type" "neon_bp_3cycle")]
3735 (define_insn "neon_vtbl4v8qi"
3736 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3737 (unspec:V8QI [(match_operand:OI 1 "s_register_operand" "w")
3738 (match_operand:V8QI 2 "s_register_operand" "w")]
3743 int tabbase = REGNO (operands[1]);
3745 ops[0] = operands[0];
3746 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3747 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3748 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3749 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
3750 ops[5] = operands[2];
3751 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
3755 [(set_attr "neon_type" "neon_bp_3cycle")]
3758 (define_insn "neon_vtbx1v8qi"
3759 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3760 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3761 (match_operand:V8QI 2 "s_register_operand" "w")
3762 (match_operand:V8QI 3 "s_register_operand" "w")]
3765 "vtbx.8\t%P0, {%P2}, %P3"
3766 [(set_attr "neon_type" "neon_bp_2cycle")]
3769 (define_insn "neon_vtbx2v8qi"
3770 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3771 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3772 (match_operand:TI 2 "s_register_operand" "w")
3773 (match_operand:V8QI 3 "s_register_operand" "w")]
3778 int tabbase = REGNO (operands[2]);
3780 ops[0] = operands[0];
3781 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3782 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3783 ops[3] = operands[3];
3784 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2}, %P3", ops);
3788 [(set_attr "neon_type" "neon_bp_2cycle")]
3791 (define_insn "neon_vtbx3v8qi"
3792 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3793 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3794 (match_operand:EI 2 "s_register_operand" "w")
3795 (match_operand:V8QI 3 "s_register_operand" "w")]
3800 int tabbase = REGNO (operands[2]);
3802 ops[0] = operands[0];
3803 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3804 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3805 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3806 ops[4] = operands[3];
3807 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
3811 [(set_attr "neon_type" "neon_bp_3cycle")]
3814 (define_insn "neon_vtbx4v8qi"
3815 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3816 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3817 (match_operand:OI 2 "s_register_operand" "w")
3818 (match_operand:V8QI 3 "s_register_operand" "w")]
3823 int tabbase = REGNO (operands[2]);
3825 ops[0] = operands[0];
3826 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3827 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3828 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3829 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
3830 ops[5] = operands[3];
3831 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
3835 [(set_attr "neon_type" "neon_bp_3cycle")]
3838 (define_insn "neon_vtrn<mode>_internal"
3839 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3840 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
3842 (set (match_operand:VDQW 2 "s_register_operand" "=w")
3843 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
3846 "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
3847 [(set (attr "neon_type")
3848 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3849 (const_string "neon_bp_simple")
3850 (const_string "neon_bp_3cycle")))]
3853 (define_expand "neon_vtrn<mode>"
3854 [(match_operand:SI 0 "s_register_operand" "r")
3855 (match_operand:VDQW 1 "s_register_operand" "w")
3856 (match_operand:VDQW 2 "s_register_operand" "w")]
3859 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vtrn<mode>_internal,
3860 operands[0], operands[1], operands[2]);
3864 (define_insn "neon_vzip<mode>_internal"
3865 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3866 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
3868 (set (match_operand:VDQW 2 "s_register_operand" "=w")
3869 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
3872 "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
3873 [(set (attr "neon_type")
3874 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3875 (const_string "neon_bp_simple")
3876 (const_string "neon_bp_3cycle")))]
3879 (define_expand "neon_vzip<mode>"
3880 [(match_operand:SI 0 "s_register_operand" "r")
3881 (match_operand:VDQW 1 "s_register_operand" "w")
3882 (match_operand:VDQW 2 "s_register_operand" "w")]
3885 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vzip<mode>_internal,
3886 operands[0], operands[1], operands[2]);
3890 (define_insn "neon_vuzp<mode>_internal"
3891 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3892 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
3894 (set (match_operand:VDQW 2 "s_register_operand" "=w")
3895 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
3898 "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
3899 [(set (attr "neon_type")
3900 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3901 (const_string "neon_bp_simple")
3902 (const_string "neon_bp_3cycle")))]
3905 (define_expand "neon_vuzp<mode>"
3906 [(match_operand:SI 0 "s_register_operand" "r")
3907 (match_operand:VDQW 1 "s_register_operand" "w")
3908 (match_operand:VDQW 2 "s_register_operand" "w")]
3911 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vuzp<mode>_internal,
3912 operands[0], operands[1], operands[2]);
3916 (define_expand "neon_vreinterpretv8qi<mode>"
3917 [(match_operand:V8QI 0 "s_register_operand" "")
3918 (match_operand:VDX 1 "s_register_operand" "")]
3921 neon_reinterpret (operands[0], operands[1]);
3925 (define_expand "neon_vreinterpretv4hi<mode>"
3926 [(match_operand:V4HI 0 "s_register_operand" "")
3927 (match_operand:VDX 1 "s_register_operand" "")]
3930 neon_reinterpret (operands[0], operands[1]);
3934 (define_expand "neon_vreinterpretv2si<mode>"
3935 [(match_operand:V2SI 0 "s_register_operand" "")
3936 (match_operand:VDX 1 "s_register_operand" "")]
3939 neon_reinterpret (operands[0], operands[1]);
3943 (define_expand "neon_vreinterpretv2sf<mode>"
3944 [(match_operand:V2SF 0 "s_register_operand" "")
3945 (match_operand:VDX 1 "s_register_operand" "")]
3948 neon_reinterpret (operands[0], operands[1]);
3952 (define_expand "neon_vreinterpretdi<mode>"
3953 [(match_operand:DI 0 "s_register_operand" "")
3954 (match_operand:VDX 1 "s_register_operand" "")]
3957 neon_reinterpret (operands[0], operands[1]);
3961 (define_expand "neon_vreinterpretv16qi<mode>"
3962 [(match_operand:V16QI 0 "s_register_operand" "")
3963 (match_operand:VQX 1 "s_register_operand" "")]
3966 neon_reinterpret (operands[0], operands[1]);
3970 (define_expand "neon_vreinterpretv8hi<mode>"
3971 [(match_operand:V8HI 0 "s_register_operand" "")
3972 (match_operand:VQX 1 "s_register_operand" "")]
3975 neon_reinterpret (operands[0], operands[1]);
3979 (define_expand "neon_vreinterpretv4si<mode>"
3980 [(match_operand:V4SI 0 "s_register_operand" "")
3981 (match_operand:VQX 1 "s_register_operand" "")]
3984 neon_reinterpret (operands[0], operands[1]);
3988 (define_expand "neon_vreinterpretv4sf<mode>"
3989 [(match_operand:V4SF 0 "s_register_operand" "")
3990 (match_operand:VQX 1 "s_register_operand" "")]
3993 neon_reinterpret (operands[0], operands[1]);
3997 (define_expand "neon_vreinterpretv2di<mode>"
3998 [(match_operand:V2DI 0 "s_register_operand" "")
3999 (match_operand:VQX 1 "s_register_operand" "")]
4002 neon_reinterpret (operands[0], operands[1]);
4006 (define_insn "neon_vld1<mode>"
4007 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
4008 (unspec:VDQX [(mem:VDQX (match_operand:SI 1 "s_register_operand" "r"))]
4011 "vld1.<V_sz_elem>\t%h0, [%1]"
4012 [(set_attr "neon_type" "neon_vld1_1_2_regs")]
4015 (define_insn "neon_vld1_lane<mode>"
4016 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4017 (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
4018 (match_operand:VDX 2 "s_register_operand" "0")
4019 (match_operand:SI 3 "immediate_operand" "i")]
4023 HOST_WIDE_INT lane = INTVAL (operands[3]);
4024 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4025 if (lane < 0 || lane >= max)
4026 error ("lane out of range");
4028 return "vld1.<V_sz_elem>\t%P0, [%1]";
4030 return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
4032 [(set (attr "neon_type")
4033 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4034 (const_string "neon_vld1_1_2_regs")
4035 (const_string "neon_vld1_vld2_lane")))]
4038 (define_insn "neon_vld1_lane<mode>"
4039 [(set (match_operand:VQX 0 "s_register_operand" "=w")
4040 (unspec:VQX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
4041 (match_operand:VQX 2 "s_register_operand" "0")
4042 (match_operand:SI 3 "immediate_operand" "i")]
4046 HOST_WIDE_INT lane = INTVAL (operands[3]);
4047 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4048 int regno = REGNO (operands[0]);
4049 if (lane < 0 || lane >= max)
4050 error ("lane out of range");
4051 else if (lane >= max / 2)
4055 operands[3] = GEN_INT (lane);
4057 operands[0] = gen_rtx_REG (<V_HALF>mode, regno);
4059 return "vld1.<V_sz_elem>\t%P0, [%1]";
4061 return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
4063 [(set (attr "neon_type")
4064 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4065 (const_string "neon_vld1_1_2_regs")
4066 (const_string "neon_vld1_vld2_lane")))]
4069 (define_insn "neon_vld1_dup<mode>"
4070 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4071 (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))]
4075 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4076 return "vld1.<V_sz_elem>\t{%P0[]}, [%1]";
4078 return "vld1.<V_sz_elem>\t%h0, [%1]";
4080 [(set (attr "neon_type")
4081 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4082 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4083 (const_string "neon_vld1_1_2_regs")))]
4086 (define_insn "neon_vld1_dup<mode>"
4087 [(set (match_operand:VQX 0 "s_register_operand" "=w")
4088 (unspec:VQX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))]
4092 if (GET_MODE_NUNITS (<MODE>mode) > 2)
4093 return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
4095 return "vld1.<V_sz_elem>\t%h0, [%1]";
4097 [(set (attr "neon_type")
4098 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4099 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4100 (const_string "neon_vld1_1_2_regs")))]
4103 (define_insn "neon_vst1<mode>"
4104 [(set (mem:VDQX (match_operand:SI 0 "s_register_operand" "r"))
4105 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")]
4108 "vst1.<V_sz_elem>\t%h1, [%0]"
4109 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
4111 (define_insn "neon_vst1_lane<mode>"
4112 [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
4113 (vec_select:<V_elem>
4114 (match_operand:VDX 1 "s_register_operand" "w")
4115 (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
4118 HOST_WIDE_INT lane = INTVAL (operands[2]);
4119 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4120 if (lane < 0 || lane >= max)
4121 error ("lane out of range");
4123 return "vst1.<V_sz_elem>\t{%P1}, [%0]";
4125 return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
4127 [(set (attr "neon_type")
4128 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 1))
4129 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4130 (const_string "neon_vst1_vst2_lane")))])
4132 (define_insn "neon_vst1_lane<mode>"
4133 [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
4134 (vec_select:<V_elem>
4135 (match_operand:VQX 1 "s_register_operand" "w")
4136 (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
4139 HOST_WIDE_INT lane = INTVAL (operands[2]);
4140 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4141 int regno = REGNO (operands[1]);
4142 if (lane < 0 || lane >= max)
4143 error ("lane out of range");
4144 else if (lane >= max / 2)
4148 operands[2] = GEN_INT (lane);
4150 operands[1] = gen_rtx_REG (<V_HALF>mode, regno);
4152 return "vst1.<V_sz_elem>\t{%P1}, [%0]";
4154 return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
4156 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4159 (define_insn "neon_vld2<mode>"
4160 [(set (match_operand:TI 0 "s_register_operand" "=w")
4161 (unspec:TI [(mem:TI (match_operand:SI 1 "s_register_operand" "r"))
4162 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4166 if (<V_sz_elem> == 64)
4167 return "vld1.64\t%h0, [%1]";
4169 return "vld2.<V_sz_elem>\t%h0, [%1]";
4171 [(set (attr "neon_type")
4172 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4173 (const_string "neon_vld1_1_2_regs")
4174 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))]
4177 (define_insn "neon_vld2<mode>"
4178 [(set (match_operand:OI 0 "s_register_operand" "=w")
4179 (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
4180 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4183 "vld2.<V_sz_elem>\t%h0, [%1]"
4184 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")])
4186 (define_insn "neon_vld2_lane<mode>"
4187 [(set (match_operand:TI 0 "s_register_operand" "=w")
4188 (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4189 (match_operand:TI 2 "s_register_operand" "0")
4190 (match_operand:SI 3 "immediate_operand" "i")
4191 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4195 HOST_WIDE_INT lane = INTVAL (operands[3]);
4196 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4197 int regno = REGNO (operands[0]);
4199 if (lane < 0 || lane >= max)
4200 error ("lane out of range");
4201 ops[0] = gen_rtx_REG (DImode, regno);
4202 ops[1] = gen_rtx_REG (DImode, regno + 2);
4203 ops[2] = operands[1];
4204 ops[3] = operands[3];
4205 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
4208 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4211 (define_insn "neon_vld2_lane<mode>"
4212 [(set (match_operand:OI 0 "s_register_operand" "=w")
4213 (unspec:OI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4214 (match_operand:OI 2 "s_register_operand" "0")
4215 (match_operand:SI 3 "immediate_operand" "i")
4216 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4220 HOST_WIDE_INT lane = INTVAL (operands[3]);
4221 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4222 int regno = REGNO (operands[0]);
4224 if (lane < 0 || lane >= max)
4225 error ("lane out of range");
4226 else if (lane >= max / 2)
4231 ops[0] = gen_rtx_REG (DImode, regno);
4232 ops[1] = gen_rtx_REG (DImode, regno + 4);
4233 ops[2] = operands[1];
4234 ops[3] = GEN_INT (lane);
4235 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
4238 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4241 (define_insn "neon_vld2_dup<mode>"
4242 [(set (match_operand:TI 0 "s_register_operand" "=w")
4243 (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4244 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4248 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4249 return "vld2.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
4251 return "vld1.<V_sz_elem>\t%h0, [%1]";
4253 [(set (attr "neon_type")
4254 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4255 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4256 (const_string "neon_vld1_1_2_regs")))]
4259 (define_insn "neon_vst2<mode>"
4260 [(set (mem:TI (match_operand:SI 0 "s_register_operand" "r"))
4261 (unspec:TI [(match_operand:TI 1 "s_register_operand" "w")
4262 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4266 if (<V_sz_elem> == 64)
4267 return "vst1.64\t%h1, [%0]";
4269 return "vst2.<V_sz_elem>\t%h1, [%0]";
4271 [(set (attr "neon_type")
4272 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4273 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4274 (const_string "neon_vst1_1_2_regs_vst2_2_regs")))]
4277 (define_insn "neon_vst2<mode>"
4278 [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
4279 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4280 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4283 "vst2.<V_sz_elem>\t%h1, [%0]"
4284 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]
4287 (define_insn "neon_vst2_lane<mode>"
4288 [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
4289 (unspec:<V_two_elem>
4290 [(match_operand:TI 1 "s_register_operand" "w")
4291 (match_operand:SI 2 "immediate_operand" "i")
4292 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4296 HOST_WIDE_INT lane = INTVAL (operands[2]);
4297 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4298 int regno = REGNO (operands[1]);
4300 if (lane < 0 || lane >= max)
4301 error ("lane out of range");
4302 ops[0] = operands[0];
4303 ops[1] = gen_rtx_REG (DImode, regno);
4304 ops[2] = gen_rtx_REG (DImode, regno + 2);
4305 ops[3] = operands[2];
4306 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
4309 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4312 (define_insn "neon_vst2_lane<mode>"
4313 [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
4314 (unspec:<V_two_elem>
4315 [(match_operand:OI 1 "s_register_operand" "w")
4316 (match_operand:SI 2 "immediate_operand" "i")
4317 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4321 HOST_WIDE_INT lane = INTVAL (operands[2]);
4322 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4323 int regno = REGNO (operands[1]);
4325 if (lane < 0 || lane >= max)
4326 error ("lane out of range");
4327 else if (lane >= max / 2)
4332 ops[0] = operands[0];
4333 ops[1] = gen_rtx_REG (DImode, regno);
4334 ops[2] = gen_rtx_REG (DImode, regno + 4);
4335 ops[3] = GEN_INT (lane);
4336 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
4339 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4342 (define_insn "neon_vld3<mode>"
4343 [(set (match_operand:EI 0 "s_register_operand" "=w")
4344 (unspec:EI [(mem:EI (match_operand:SI 1 "s_register_operand" "r"))
4345 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4349 if (<V_sz_elem> == 64)
4350 return "vld1.64\t%h0, [%1]";
4352 return "vld3.<V_sz_elem>\t%h0, [%1]";
4354 [(set (attr "neon_type")
4355 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4356 (const_string "neon_vld1_1_2_regs")
4357 (const_string "neon_vld3_vld4")))]
4360 (define_expand "neon_vld3<mode>"
4361 [(match_operand:CI 0 "s_register_operand" "=w")
4362 (match_operand:SI 1 "s_register_operand" "+r")
4363 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4366 emit_insn (gen_neon_vld3qa<mode> (operands[0], operands[0],
4367 operands[1], operands[1]));
4368 emit_insn (gen_neon_vld3qb<mode> (operands[0], operands[0],
4369 operands[1], operands[1]));
4373 (define_insn "neon_vld3qa<mode>"
4374 [(set (match_operand:CI 0 "s_register_operand" "=w")
4375 (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
4376 (match_operand:CI 1 "s_register_operand" "0")
4377 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4379 (set (match_operand:SI 2 "s_register_operand" "=r")
4380 (plus:SI (match_dup 3)
4384 int regno = REGNO (operands[0]);
4386 ops[0] = gen_rtx_REG (DImode, regno);
4387 ops[1] = gen_rtx_REG (DImode, regno + 4);
4388 ops[2] = gen_rtx_REG (DImode, regno + 8);
4389 ops[3] = operands[2];
4390 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
4393 [(set_attr "neon_type" "neon_vld3_vld4")]
4396 (define_insn "neon_vld3qb<mode>"
4397 [(set (match_operand:CI 0 "s_register_operand" "=w")
4398 (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
4399 (match_operand:CI 1 "s_register_operand" "0")
4400 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4402 (set (match_operand:SI 2 "s_register_operand" "=r")
4403 (plus:SI (match_dup 3)
4407 int regno = REGNO (operands[0]);
4409 ops[0] = gen_rtx_REG (DImode, regno + 2);
4410 ops[1] = gen_rtx_REG (DImode, regno + 6);
4411 ops[2] = gen_rtx_REG (DImode, regno + 10);
4412 ops[3] = operands[2];
4413 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
4416 [(set_attr "neon_type" "neon_vld3_vld4")]
4419 (define_insn "neon_vld3_lane<mode>"
4420 [(set (match_operand:EI 0 "s_register_operand" "=w")
4421 (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4422 (match_operand:EI 2 "s_register_operand" "0")
4423 (match_operand:SI 3 "immediate_operand" "i")
4424 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4428 HOST_WIDE_INT lane = INTVAL (operands[3]);
4429 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4430 int regno = REGNO (operands[0]);
4432 if (lane < 0 || lane >= max)
4433 error ("lane out of range");
4434 ops[0] = gen_rtx_REG (DImode, regno);
4435 ops[1] = gen_rtx_REG (DImode, regno + 2);
4436 ops[2] = gen_rtx_REG (DImode, regno + 4);
4437 ops[3] = operands[1];
4438 ops[4] = operands[3];
4439 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
4443 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4446 (define_insn "neon_vld3_lane<mode>"
4447 [(set (match_operand:CI 0 "s_register_operand" "=w")
4448 (unspec:CI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4449 (match_operand:CI 2 "s_register_operand" "0")
4450 (match_operand:SI 3 "immediate_operand" "i")
4451 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4455 HOST_WIDE_INT lane = INTVAL (operands[3]);
4456 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4457 int regno = REGNO (operands[0]);
4459 if (lane < 0 || lane >= max)
4460 error ("lane out of range");
4461 else if (lane >= max / 2)
4466 ops[0] = gen_rtx_REG (DImode, regno);
4467 ops[1] = gen_rtx_REG (DImode, regno + 4);
4468 ops[2] = gen_rtx_REG (DImode, regno + 8);
4469 ops[3] = operands[1];
4470 ops[4] = GEN_INT (lane);
4471 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
4475 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4478 (define_insn "neon_vld3_dup<mode>"
4479 [(set (match_operand:EI 0 "s_register_operand" "=w")
4480 (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4481 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4485 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4487 int regno = REGNO (operands[0]);
4489 ops[0] = gen_rtx_REG (DImode, regno);
4490 ops[1] = gen_rtx_REG (DImode, regno + 2);
4491 ops[2] = gen_rtx_REG (DImode, regno + 4);
4492 ops[3] = operands[1];
4493 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[], %P1[], %P2[]}, [%3]", ops);
4497 return "vld1.<V_sz_elem>\t%h0, [%1]";
4499 [(set (attr "neon_type")
4500 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4501 (const_string "neon_vld3_vld4_all_lanes")
4502 (const_string "neon_vld1_1_2_regs")))])
4504 (define_insn "neon_vst3<mode>"
4505 [(set (mem:EI (match_operand:SI 0 "s_register_operand" "r"))
4506 (unspec:EI [(match_operand:EI 1 "s_register_operand" "w")
4507 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4511 if (<V_sz_elem> == 64)
4512 return "vst1.64\t%h1, [%0]";
4514 return "vst3.<V_sz_elem>\t%h1, [%0]";
4516 [(set (attr "neon_type")
4517 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4518 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4519 (const_string "neon_vst2_4_regs_vst3_vst4")))])
4521 (define_expand "neon_vst3<mode>"
4522 [(match_operand:SI 0 "s_register_operand" "+r")
4523 (match_operand:CI 1 "s_register_operand" "w")
4524 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4527 emit_insn (gen_neon_vst3qa<mode> (operands[0], operands[0], operands[1]));
4528 emit_insn (gen_neon_vst3qb<mode> (operands[0], operands[0], operands[1]));
4532 (define_insn "neon_vst3qa<mode>"
4533 [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
4534 (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
4535 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4537 (set (match_operand:SI 0 "s_register_operand" "=r")
4538 (plus:SI (match_dup 1)
4542 int regno = REGNO (operands[2]);
4544 ops[0] = operands[0];
4545 ops[1] = gen_rtx_REG (DImode, regno);
4546 ops[2] = gen_rtx_REG (DImode, regno + 4);
4547 ops[3] = gen_rtx_REG (DImode, regno + 8);
4548 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
4551 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4554 (define_insn "neon_vst3qb<mode>"
4555 [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
4556 (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
4557 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4559 (set (match_operand:SI 0 "s_register_operand" "=r")
4560 (plus:SI (match_dup 1)
4564 int regno = REGNO (operands[2]);
4566 ops[0] = operands[0];
4567 ops[1] = gen_rtx_REG (DImode, regno + 2);
4568 ops[2] = gen_rtx_REG (DImode, regno + 6);
4569 ops[3] = gen_rtx_REG (DImode, regno + 10);
4570 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
4573 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4576 (define_insn "neon_vst3_lane<mode>"
4577 [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
4578 (unspec:<V_three_elem>
4579 [(match_operand:EI 1 "s_register_operand" "w")
4580 (match_operand:SI 2 "immediate_operand" "i")
4581 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4585 HOST_WIDE_INT lane = INTVAL (operands[2]);
4586 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4587 int regno = REGNO (operands[1]);
4589 if (lane < 0 || lane >= max)
4590 error ("lane out of range");
4591 ops[0] = operands[0];
4592 ops[1] = gen_rtx_REG (DImode, regno);
4593 ops[2] = gen_rtx_REG (DImode, regno + 2);
4594 ops[3] = gen_rtx_REG (DImode, regno + 4);
4595 ops[4] = operands[2];
4596 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
4600 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
4603 (define_insn "neon_vst3_lane<mode>"
4604 [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
4605 (unspec:<V_three_elem>
4606 [(match_operand:CI 1 "s_register_operand" "w")
4607 (match_operand:SI 2 "immediate_operand" "i")
4608 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4612 HOST_WIDE_INT lane = INTVAL (operands[2]);
4613 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4614 int regno = REGNO (operands[1]);
4616 if (lane < 0 || lane >= max)
4617 error ("lane out of range");
4618 else if (lane >= max / 2)
4623 ops[0] = operands[0];
4624 ops[1] = gen_rtx_REG (DImode, regno);
4625 ops[2] = gen_rtx_REG (DImode, regno + 4);
4626 ops[3] = gen_rtx_REG (DImode, regno + 8);
4627 ops[4] = GEN_INT (lane);
4628 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
4632 [(set_attr "neon_type" "neon_vst3_vst4_lane")])
4634 (define_insn "neon_vld4<mode>"
4635 [(set (match_operand:OI 0 "s_register_operand" "=w")
4636 (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
4637 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4641 if (<V_sz_elem> == 64)
4642 return "vld1.64\t%h0, [%1]";
4644 return "vld4.<V_sz_elem>\t%h0, [%1]";
4646 [(set (attr "neon_type")
4647 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4648 (const_string "neon_vld1_1_2_regs")
4649 (const_string "neon_vld3_vld4")))]
4652 (define_expand "neon_vld4<mode>"
4653 [(match_operand:XI 0 "s_register_operand" "=w")
4654 (match_operand:SI 1 "s_register_operand" "+r")
4655 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4658 emit_insn (gen_neon_vld4qa<mode> (operands[0], operands[0],
4659 operands[1], operands[1]));
4660 emit_insn (gen_neon_vld4qb<mode> (operands[0], operands[0],
4661 operands[1], operands[1]));
4665 (define_insn "neon_vld4qa<mode>"
4666 [(set (match_operand:XI 0 "s_register_operand" "=w")
4667 (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
4668 (match_operand:XI 1 "s_register_operand" "0")
4669 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4671 (set (match_operand:SI 2 "s_register_operand" "=r")
4672 (plus:SI (match_dup 3)
4676 int regno = REGNO (operands[0]);
4678 ops[0] = gen_rtx_REG (DImode, regno);
4679 ops[1] = gen_rtx_REG (DImode, regno + 4);
4680 ops[2] = gen_rtx_REG (DImode, regno + 8);
4681 ops[3] = gen_rtx_REG (DImode, regno + 12);
4682 ops[4] = operands[2];
4683 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
4686 [(set_attr "neon_type" "neon_vld3_vld4")]
4689 (define_insn "neon_vld4qb<mode>"
4690 [(set (match_operand:XI 0 "s_register_operand" "=w")
4691 (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
4692 (match_operand:XI 1 "s_register_operand" "0")
4693 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4695 (set (match_operand:SI 2 "s_register_operand" "=r")
4696 (plus:SI (match_dup 3)
4700 int regno = REGNO (operands[0]);
4702 ops[0] = gen_rtx_REG (DImode, regno + 2);
4703 ops[1] = gen_rtx_REG (DImode, regno + 6);
4704 ops[2] = gen_rtx_REG (DImode, regno + 10);
4705 ops[3] = gen_rtx_REG (DImode, regno + 14);
4706 ops[4] = operands[2];
4707 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
4710 [(set_attr "neon_type" "neon_vld3_vld4")]
4713 (define_insn "neon_vld4_lane<mode>"
4714 [(set (match_operand:OI 0 "s_register_operand" "=w")
4715 (unspec:OI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
4716 (match_operand:OI 2 "s_register_operand" "0")
4717 (match_operand:SI 3 "immediate_operand" "i")
4718 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4722 HOST_WIDE_INT lane = INTVAL (operands[3]);
4723 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4724 int regno = REGNO (operands[0]);
4726 if (lane < 0 || lane >= max)
4727 error ("lane out of range");
4728 ops[0] = gen_rtx_REG (DImode, regno);
4729 ops[1] = gen_rtx_REG (DImode, regno + 2);
4730 ops[2] = gen_rtx_REG (DImode, regno + 4);
4731 ops[3] = gen_rtx_REG (DImode, regno + 6);
4732 ops[4] = operands[1];
4733 ops[5] = operands[3];
4734 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
4738 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4741 (define_insn "neon_vld4_lane<mode>"
4742 [(set (match_operand:XI 0 "s_register_operand" "=w")
4743 (unspec:XI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
4744 (match_operand:XI 2 "s_register_operand" "0")
4745 (match_operand:SI 3 "immediate_operand" "i")
4746 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4750 HOST_WIDE_INT lane = INTVAL (operands[3]);
4751 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4752 int regno = REGNO (operands[0]);
4754 if (lane < 0 || lane >= max)
4755 error ("lane out of range");
4756 else if (lane >= max / 2)
4761 ops[0] = gen_rtx_REG (DImode, regno);
4762 ops[1] = gen_rtx_REG (DImode, regno + 4);
4763 ops[2] = gen_rtx_REG (DImode, regno + 8);
4764 ops[3] = gen_rtx_REG (DImode, regno + 12);
4765 ops[4] = operands[1];
4766 ops[5] = GEN_INT (lane);
4767 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
4771 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4774 (define_insn "neon_vld4_dup<mode>"
4775 [(set (match_operand:OI 0 "s_register_operand" "=w")
4776 (unspec:OI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
4777 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4781 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4783 int regno = REGNO (operands[0]);
4785 ops[0] = gen_rtx_REG (DImode, regno);
4786 ops[1] = gen_rtx_REG (DImode, regno + 2);
4787 ops[2] = gen_rtx_REG (DImode, regno + 4);
4788 ops[3] = gen_rtx_REG (DImode, regno + 6);
4789 ops[4] = operands[1];
4790 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[], %P1[], %P2[], %P3[]}, [%4]",
4795 return "vld1.<V_sz_elem>\t%h0, [%1]";
4797 [(set (attr "neon_type")
4798 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4799 (const_string "neon_vld3_vld4_all_lanes")
4800 (const_string "neon_vld1_1_2_regs")))]
4803 (define_insn "neon_vst4<mode>"
4804 [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
4805 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4806 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4810 if (<V_sz_elem> == 64)
4811 return "vst1.64\t%h1, [%0]";
4813 return "vst4.<V_sz_elem>\t%h1, [%0]";
4815 [(set (attr "neon_type")
4816 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4817 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4818 (const_string "neon_vst2_4_regs_vst3_vst4")))]
4821 (define_expand "neon_vst4<mode>"
4822 [(match_operand:SI 0 "s_register_operand" "+r")
4823 (match_operand:XI 1 "s_register_operand" "w")
4824 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4827 emit_insn (gen_neon_vst4qa<mode> (operands[0], operands[0], operands[1]));
4828 emit_insn (gen_neon_vst4qb<mode> (operands[0], operands[0], operands[1]));
4832 (define_insn "neon_vst4qa<mode>"
4833 [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
4834 (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
4835 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4837 (set (match_operand:SI 0 "s_register_operand" "=r")
4838 (plus:SI (match_dup 1)
4842 int regno = REGNO (operands[2]);
4844 ops[0] = operands[0];
4845 ops[1] = gen_rtx_REG (DImode, regno);
4846 ops[2] = gen_rtx_REG (DImode, regno + 4);
4847 ops[3] = gen_rtx_REG (DImode, regno + 8);
4848 ops[4] = gen_rtx_REG (DImode, regno + 12);
4849 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
4852 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4855 (define_insn "neon_vst4qb<mode>"
4856 [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
4857 (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
4858 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4860 (set (match_operand:SI 0 "s_register_operand" "=r")
4861 (plus:SI (match_dup 1)
4865 int regno = REGNO (operands[2]);
4867 ops[0] = operands[0];
4868 ops[1] = gen_rtx_REG (DImode, regno + 2);
4869 ops[2] = gen_rtx_REG (DImode, regno + 6);
4870 ops[3] = gen_rtx_REG (DImode, regno + 10);
4871 ops[4] = gen_rtx_REG (DImode, regno + 14);
4872 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
4875 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4878 (define_insn "neon_vst4_lane<mode>"
4879 [(set (mem:<V_four_elem> (match_operand:SI 0 "s_register_operand" "r"))
4880 (unspec:<V_four_elem>
4881 [(match_operand:OI 1 "s_register_operand" "w")
4882 (match_operand:SI 2 "immediate_operand" "i")
4883 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4887 HOST_WIDE_INT lane = INTVAL (operands[2]);
4888 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4889 int regno = REGNO (operands[1]);
4891 if (lane < 0 || lane >= max)
4892 error ("lane out of range");
4893 ops[0] = operands[0];
4894 ops[1] = gen_rtx_REG (DImode, regno);
4895 ops[2] = gen_rtx_REG (DImode, regno + 2);
4896 ops[3] = gen_rtx_REG (DImode, regno + 4);
4897 ops[4] = gen_rtx_REG (DImode, regno + 6);
4898 ops[5] = operands[2];
4899 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, [%0]",
4903 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
4906 (define_insn "neon_vst4_lane<mode>"
4907 [(set (mem:<V_four_elem> (match_operand:SI 0 "s_register_operand" "r"))
4908 (unspec:<V_four_elem>
4909 [(match_operand:XI 1 "s_register_operand" "w")
4910 (match_operand:SI 2 "immediate_operand" "i")
4911 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4915 HOST_WIDE_INT lane = INTVAL (operands[2]);
4916 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4917 int regno = REGNO (operands[1]);
4919 if (lane < 0 || lane >= max)
4920 error ("lane out of range");
4921 else if (lane >= max / 2)
4926 ops[0] = operands[0];
4927 ops[1] = gen_rtx_REG (DImode, regno);
4928 ops[2] = gen_rtx_REG (DImode, regno + 4);
4929 ops[3] = gen_rtx_REG (DImode, regno + 8);
4930 ops[4] = gen_rtx_REG (DImode, regno + 12);
4931 ops[5] = GEN_INT (lane);
4932 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, [%0]",
4936 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
4939 (define_expand "neon_vand<mode>"
4940 [(match_operand:VDQX 0 "s_register_operand" "")
4941 (match_operand:VDQX 1 "s_register_operand" "")
4942 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
4943 (match_operand:SI 3 "immediate_operand" "")]
4946 emit_insn (gen_and<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
4950 (define_expand "neon_vorr<mode>"
4951 [(match_operand:VDQX 0 "s_register_operand" "")
4952 (match_operand:VDQX 1 "s_register_operand" "")
4953 (match_operand:VDQX 2 "neon_logic_op2" "")
4954 (match_operand:SI 3 "immediate_operand" "")]
4957 emit_insn (gen_ior<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
4961 (define_expand "neon_veor<mode>"
4962 [(match_operand:VDQX 0 "s_register_operand" "")
4963 (match_operand:VDQX 1 "s_register_operand" "")
4964 (match_operand:VDQX 2 "s_register_operand" "")
4965 (match_operand:SI 3 "immediate_operand" "")]
4968 emit_insn (gen_xor<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
4972 (define_expand "neon_vbic<mode>"
4973 [(match_operand:VDQX 0 "s_register_operand" "")
4974 (match_operand:VDQX 1 "s_register_operand" "")
4975 (match_operand:VDQX 2 "neon_logic_op2" "")
4976 (match_operand:SI 3 "immediate_operand" "")]
4979 emit_insn (gen_bic<mode>3_neon (operands[0], operands[1], operands[2]));
4983 (define_expand "neon_vorn<mode>"
4984 [(match_operand:VDQX 0 "s_register_operand" "")
4985 (match_operand:VDQX 1 "s_register_operand" "")
4986 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
4987 (match_operand:SI 3 "immediate_operand" "")]
4990 emit_insn (gen_orn<mode>3_neon (operands[0], operands[1], operands[2]));