1 ;; ARM NEON coprocessor Machine Description
2 ;; Copyright (C) 2006, 2007, 2008, 2009 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 ;; Predicates used for setting neon_type
432 (define_mode_attr Is_float_mode [(V8QI "false") (V16QI "false")
433 (V4HI "false") (V8HI "false")
434 (V2SI "false") (V4SI "false")
435 (V2SF "true") (V4SF "true")
436 (DI "false") (V2DI "false")])
438 (define_mode_attr Scalar_mul_8_16 [(V8QI "true") (V16QI "true")
439 (V4HI "true") (V8HI "true")
440 (V2SI "false") (V4SI "false")
441 (V2SF "false") (V4SF "false")
442 (DI "false") (V2DI "false")])
445 (define_mode_attr Is_d_reg [(V8QI "true") (V16QI "false")
446 (V4HI "true") (V8HI "false")
447 (V2SI "true") (V4SI "false")
448 (V2SF "true") (V4SF "false")
449 (DI "true") (V2DI "false")])
451 (define_mode_attr V_mode_nunits [(V8QI "8") (V16QI "16")
452 (V4HI "4") (V8HI "8")
453 (V2SI "2") (V4SI "4")
454 (V2SF "2") (V4SF "4")
455 (DI "1") (V2DI "2")])
457 (define_insn "*neon_mov<mode>"
458 [(set (match_operand:VD 0 "nonimmediate_operand"
459 "=w,Uv,w, w, ?r,?w,?r,?r, ?Us")
460 (match_operand:VD 1 "general_operand"
461 " w,w, Dn,Uvi, w, r, r, Usi,r"))]
463 && (register_operand (operands[0], <MODE>mode)
464 || register_operand (operands[1], <MODE>mode))"
466 if (which_alternative == 2)
469 static char templ[40];
471 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
472 &operands[1], &width);
474 gcc_assert (is_valid != 0);
477 return "vmov.f32\t%P0, %1 @ <mode>";
479 sprintf (templ, "vmov.i%d\t%%P0, %%1 @ <mode>", width);
484 /* FIXME: If the memory layout is changed in big-endian mode, output_move_vfp
485 below must be changed to output_move_neon (which will use the
486 element/structure loads/stores), and the constraint changed to 'Um' instead
489 switch (which_alternative)
491 case 0: return "vmov\t%P0, %P1 @ <mode>";
492 case 1: case 3: return output_move_vfp (operands);
493 case 2: gcc_unreachable ();
494 case 4: return "vmov\t%Q0, %R0, %P1 @ <mode>";
495 case 5: return "vmov\t%P0, %Q1, %R1 @ <mode>";
496 default: return output_move_double (operands);
499 [(set_attr "neon_type" "neon_int_1,*,neon_vmov,*,neon_mrrc,neon_mcr_2_mcrr,*,*,*")
500 (set_attr "type" "*,f_stored,*,f_loadd,*,*,alu,load2,store2")
501 (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
502 (set_attr "length" "4,4,4,4,4,4,8,8,8")
503 (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
504 (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
506 (define_insn "*neon_mov<mode>"
507 [(set (match_operand:VQXMOV 0 "nonimmediate_operand"
508 "=w,Un,w, w, ?r,?w,?r,?r, ?Us")
509 (match_operand:VQXMOV 1 "general_operand"
510 " w,w, Dn,Uni, w, r, r, Usi, r"))]
512 && (register_operand (operands[0], <MODE>mode)
513 || register_operand (operands[1], <MODE>mode))"
515 if (which_alternative == 2)
518 static char templ[40];
520 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
521 &operands[1], &width);
523 gcc_assert (is_valid != 0);
526 return "vmov.f32\t%q0, %1 @ <mode>";
528 sprintf (templ, "vmov.i%d\t%%q0, %%1 @ <mode>", width);
533 switch (which_alternative)
535 case 0: return "vmov\t%q0, %q1 @ <mode>";
536 case 1: case 3: return output_move_neon (operands);
537 case 2: gcc_unreachable ();
538 case 4: return "vmov\t%Q0, %R0, %e1 @ <mode>\;vmov\t%J0, %K0, %f1";
539 case 5: return "vmov\t%e0, %Q1, %R1 @ <mode>\;vmov\t%f0, %J1, %K1";
540 default: return output_move_quad (operands);
543 [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\
544 neon_mrrc,neon_mcr_2_mcrr,*,*,*")
545 (set_attr "type" "*,*,*,*,*,*,alu,load4,store4")
546 (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
547 (set_attr "length" "4,8,4,8,8,8,16,8,16")
548 (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
549 (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
551 (define_expand "movti"
552 [(set (match_operand:TI 0 "nonimmediate_operand" "")
553 (match_operand:TI 1 "general_operand" ""))]
556 if (can_create_pseudo_p ())
558 if (GET_CODE (operands[0]) != REG)
559 operands[1] = force_reg (TImode, operands[1]);
563 (define_expand "mov<mode>"
564 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "")
565 (match_operand:VSTRUCT 1 "general_operand" ""))]
568 if (can_create_pseudo_p ())
570 if (GET_CODE (operands[0]) != REG)
571 operands[1] = force_reg (<MODE>mode, operands[1]);
575 (define_insn "*neon_mov<mode>"
576 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "=w,Ut,w")
577 (match_operand:VSTRUCT 1 "general_operand" " w,w, Ut"))]
579 && (register_operand (operands[0], <MODE>mode)
580 || register_operand (operands[1], <MODE>mode))"
582 switch (which_alternative)
585 case 1: case 2: return output_move_neon (operands);
586 default: gcc_unreachable ();
589 [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_ldm_2")
590 (set_attr "length" "<V_slen>,<V_slen>,<V_slen>")])
593 [(set (match_operand:EI 0 "s_register_operand" "")
594 (match_operand:EI 1 "s_register_operand" ""))]
595 "TARGET_NEON && reload_completed"
596 [(set (match_dup 0) (match_dup 1))
597 (set (match_dup 2) (match_dup 3))]
599 int rdest = REGNO (operands[0]);
600 int rsrc = REGNO (operands[1]);
603 dest[0] = gen_rtx_REG (TImode, rdest);
604 src[0] = gen_rtx_REG (TImode, rsrc);
605 dest[1] = gen_rtx_REG (DImode, rdest + 4);
606 src[1] = gen_rtx_REG (DImode, rsrc + 4);
608 neon_disambiguate_copy (operands, dest, src, 2);
612 [(set (match_operand:OI 0 "s_register_operand" "")
613 (match_operand:OI 1 "s_register_operand" ""))]
614 "TARGET_NEON && reload_completed"
615 [(set (match_dup 0) (match_dup 1))
616 (set (match_dup 2) (match_dup 3))]
618 int rdest = REGNO (operands[0]);
619 int rsrc = REGNO (operands[1]);
622 dest[0] = gen_rtx_REG (TImode, rdest);
623 src[0] = gen_rtx_REG (TImode, rsrc);
624 dest[1] = gen_rtx_REG (TImode, rdest + 4);
625 src[1] = gen_rtx_REG (TImode, rsrc + 4);
627 neon_disambiguate_copy (operands, dest, src, 2);
631 [(set (match_operand:CI 0 "s_register_operand" "")
632 (match_operand:CI 1 "s_register_operand" ""))]
633 "TARGET_NEON && reload_completed"
634 [(set (match_dup 0) (match_dup 1))
635 (set (match_dup 2) (match_dup 3))
636 (set (match_dup 4) (match_dup 5))]
638 int rdest = REGNO (operands[0]);
639 int rsrc = REGNO (operands[1]);
642 dest[0] = gen_rtx_REG (TImode, rdest);
643 src[0] = gen_rtx_REG (TImode, rsrc);
644 dest[1] = gen_rtx_REG (TImode, rdest + 4);
645 src[1] = gen_rtx_REG (TImode, rsrc + 4);
646 dest[2] = gen_rtx_REG (TImode, rdest + 8);
647 src[2] = gen_rtx_REG (TImode, rsrc + 8);
649 neon_disambiguate_copy (operands, dest, src, 3);
653 [(set (match_operand:XI 0 "s_register_operand" "")
654 (match_operand:XI 1 "s_register_operand" ""))]
655 "TARGET_NEON && reload_completed"
656 [(set (match_dup 0) (match_dup 1))
657 (set (match_dup 2) (match_dup 3))
658 (set (match_dup 4) (match_dup 5))
659 (set (match_dup 6) (match_dup 7))]
661 int rdest = REGNO (operands[0]);
662 int rsrc = REGNO (operands[1]);
665 dest[0] = gen_rtx_REG (TImode, rdest);
666 src[0] = gen_rtx_REG (TImode, rsrc);
667 dest[1] = gen_rtx_REG (TImode, rdest + 4);
668 src[1] = gen_rtx_REG (TImode, rsrc + 4);
669 dest[2] = gen_rtx_REG (TImode, rdest + 8);
670 src[2] = gen_rtx_REG (TImode, rsrc + 8);
671 dest[3] = gen_rtx_REG (TImode, rdest + 12);
672 src[3] = gen_rtx_REG (TImode, rsrc + 12);
674 neon_disambiguate_copy (operands, dest, src, 4);
677 (define_insn "vec_set<mode>_internal"
678 [(set (match_operand:VD 0 "s_register_operand" "=w")
681 (match_operand:<V_elem> 1 "s_register_operand" "r"))
682 (match_operand:VD 3 "s_register_operand" "0")
683 (match_operand:SI 2 "immediate_operand" "i")))]
686 int elt = ffs ((int) INTVAL (operands[2]) - 1);
687 if (BYTES_BIG_ENDIAN)
688 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
689 operands[2] = GEN_INT (elt);
691 return "vmov%?.<V_uf_sclr>\t%P0[%c2], %1";
693 [(set_attr "predicable" "yes")
694 (set_attr "neon_type" "neon_mcr")])
696 (define_insn "vec_set<mode>_internal"
697 [(set (match_operand:VQ 0 "s_register_operand" "=w")
700 (match_operand:<V_elem> 1 "s_register_operand" "r"))
701 (match_operand:VQ 3 "s_register_operand" "0")
702 (match_operand:SI 2 "immediate_operand" "i")))]
705 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
706 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
707 int elt = elem % half_elts;
708 int hi = (elem / half_elts) * 2;
709 int regno = REGNO (operands[0]);
711 if (BYTES_BIG_ENDIAN)
712 elt = half_elts - 1 - elt;
714 operands[0] = gen_rtx_REG (<V_HALF>mode, regno + hi);
715 operands[2] = GEN_INT (elt);
717 return "vmov%?.<V_uf_sclr>\t%P0[%c2], %1";
719 [(set_attr "predicable" "yes")
720 (set_attr "neon_type" "neon_mcr")]
723 (define_insn "vec_setv2di_internal"
724 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
727 (match_operand:DI 1 "s_register_operand" "r"))
728 (match_operand:V2DI 3 "s_register_operand" "0")
729 (match_operand:SI 2 "immediate_operand" "i")))]
732 HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
733 int regno = REGNO (operands[0]) + 2 * elem;
735 operands[0] = gen_rtx_REG (DImode, regno);
737 return "vmov%?.64\t%P0, %Q1, %R1";
739 [(set_attr "predicable" "yes")
740 (set_attr "neon_type" "neon_mcr_2_mcrr")]
743 (define_expand "vec_set<mode>"
744 [(match_operand:VDQ 0 "s_register_operand" "")
745 (match_operand:<V_elem> 1 "s_register_operand" "")
746 (match_operand:SI 2 "immediate_operand" "")]
749 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
750 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
751 GEN_INT (elem), operands[0]));
755 (define_insn "vec_extract<mode>"
756 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
758 (match_operand:VD 1 "s_register_operand" "w")
759 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
762 if (BYTES_BIG_ENDIAN)
764 int elt = INTVAL (operands[2]);
765 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
766 operands[2] = GEN_INT (elt);
768 return "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]";
770 [(set_attr "predicable" "yes")
771 (set_attr "neon_type" "neon_bp_simple")]
774 (define_insn "vec_extract<mode>"
775 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
777 (match_operand:VQ 1 "s_register_operand" "w")
778 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
781 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
782 int elt = INTVAL (operands[2]) % half_elts;
783 int hi = (INTVAL (operands[2]) / half_elts) * 2;
784 int regno = REGNO (operands[1]);
786 if (BYTES_BIG_ENDIAN)
787 elt = half_elts - 1 - elt;
789 operands[1] = gen_rtx_REG (<V_HALF>mode, regno + hi);
790 operands[2] = GEN_INT (elt);
792 return "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]";
794 [(set_attr "predicable" "yes")
795 (set_attr "neon_type" "neon_bp_simple")]
798 (define_insn "vec_extractv2di"
799 [(set (match_operand:DI 0 "s_register_operand" "=r")
801 (match_operand:V2DI 1 "s_register_operand" "w")
802 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
805 int regno = REGNO (operands[1]) + INTVAL (operands[2]);
807 operands[1] = gen_rtx_REG (DImode, regno);
809 return "vmov%?.64\t%Q0, %R0, %P1";
811 [(set_attr "predicable" "yes")
812 (set_attr "neon_type" "neon_int_1")]
815 (define_expand "vec_init<mode>"
816 [(match_operand:VDQ 0 "s_register_operand" "")
817 (match_operand 1 "" "")]
820 neon_expand_vector_init (operands[0], operands[1]);
824 ;; Doubleword and quadword arithmetic.
826 ;; NOTE: vadd/vsub and some other instructions also support 64-bit integer
827 ;; element size, which we could potentially use for "long long" operations. We
828 ;; don't want to do this at present though, because moving values from the
829 ;; vector unit to the ARM core is currently slow and 64-bit addition (etc.) is
830 ;; easy to do with ARM instructions anyway.
832 (define_insn "*add<mode>3_neon"
833 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
834 (plus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
835 (match_operand:VDQ 2 "s_register_operand" "w")))]
837 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
838 [(set (attr "neon_type")
839 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
840 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
841 (const_string "neon_fp_vadd_ddd_vabs_dd")
842 (const_string "neon_fp_vadd_qqq_vabs_qq"))
843 (const_string "neon_int_1")))]
846 (define_insn "*sub<mode>3_neon"
847 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
848 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
849 (match_operand:VDQ 2 "s_register_operand" "w")))]
851 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
852 [(set (attr "neon_type")
853 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
854 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
855 (const_string "neon_fp_vadd_ddd_vabs_dd")
856 (const_string "neon_fp_vadd_qqq_vabs_qq"))
857 (const_string "neon_int_2")))]
860 (define_insn "*mul<mode>3_neon"
861 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
862 (mult:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
863 (match_operand:VDQ 2 "s_register_operand" "w")))]
865 "vmul.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
866 [(set (attr "neon_type")
867 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
868 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
869 (const_string "neon_fp_vadd_ddd_vabs_dd")
870 (const_string "neon_fp_vadd_qqq_vabs_qq"))
871 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
873 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
874 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
875 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
876 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
877 (const_string "neon_mul_qqq_8_16_32_ddd_32")
878 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
881 (define_insn "*mul<mode>3add<mode>_neon"
882 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
883 (plus:VDQ (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
884 (match_operand:VDQ 3 "s_register_operand" "w"))
885 (match_operand:VDQ 1 "s_register_operand" "0")))]
887 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
888 [(set (attr "neon_type")
889 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
890 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
891 (const_string "neon_fp_vmla_ddd")
892 (const_string "neon_fp_vmla_qqq"))
893 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
895 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
896 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
897 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
898 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
899 (const_string "neon_mla_qqq_8_16")
900 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
903 (define_insn "*mul<mode>3neg<mode>add<mode>_neon"
904 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
905 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "0")
906 (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
907 (match_operand:VDQ 3 "s_register_operand" "w"))))]
909 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
910 [(set (attr "neon_type")
911 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
912 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
913 (const_string "neon_fp_vmla_ddd")
914 (const_string "neon_fp_vmla_qqq"))
915 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
917 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
918 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
919 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
920 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
921 (const_string "neon_mla_qqq_8_16")
922 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
925 (define_insn "ior<mode>3"
926 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
927 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
928 (match_operand:VDQ 2 "neon_logic_op2" "w,Dl")))]
931 switch (which_alternative)
933 case 0: return "vorr\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
934 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
935 <MODE>mode, 0, VALID_NEON_QREG_MODE (<MODE>mode));
936 default: gcc_unreachable ();
939 [(set_attr "neon_type" "neon_int_1")]
942 (define_insn "iordi3_neon"
943 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
944 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w,0")
945 (match_operand:DI 2 "neon_logic_op2" "w,Dl")]
949 switch (which_alternative)
951 case 0: return "vorr\t%P0, %P1, %P2";
952 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
953 DImode, 0, VALID_NEON_QREG_MODE (DImode));
954 default: gcc_unreachable ();
957 [(set_attr "neon_type" "neon_int_1")]
960 ;; The concrete forms of the Neon immediate-logic instructions are vbic and
961 ;; vorr. We support the pseudo-instruction vand instead, because that
962 ;; corresponds to the canonical form the middle-end expects to use for
963 ;; immediate bitwise-ANDs.
965 (define_insn "and<mode>3"
966 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
967 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
968 (match_operand:VDQ 2 "neon_inv_logic_op2" "w,DL")))]
971 switch (which_alternative)
973 case 0: return "vand\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
974 case 1: return neon_output_logic_immediate ("vand", &operands[2],
975 <MODE>mode, 1, VALID_NEON_QREG_MODE (<MODE>mode));
976 default: gcc_unreachable ();
979 [(set_attr "neon_type" "neon_int_1")]
982 (define_insn "anddi3_neon"
983 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
984 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w,0")
985 (match_operand:DI 2 "neon_inv_logic_op2" "w,DL")]
989 switch (which_alternative)
991 case 0: return "vand\t%P0, %P1, %P2";
992 case 1: return neon_output_logic_immediate ("vand", &operands[2],
993 DImode, 1, VALID_NEON_QREG_MODE (DImode));
994 default: gcc_unreachable ();
997 [(set_attr "neon_type" "neon_int_1")]
1000 (define_insn "orn<mode>3_neon"
1001 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1002 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
1003 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
1005 "vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1006 [(set_attr "neon_type" "neon_int_1")]
1009 (define_insn "orndi3_neon"
1010 [(set (match_operand:DI 0 "s_register_operand" "=w")
1011 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
1012 (match_operand:DI 2 "s_register_operand" "w")]
1015 "vorn\t%P0, %P1, %P2"
1016 [(set_attr "neon_type" "neon_int_1")]
1019 (define_insn "bic<mode>3_neon"
1020 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1021 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
1022 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
1024 "vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1025 [(set_attr "neon_type" "neon_int_1")]
1028 (define_insn "bicdi3_neon"
1029 [(set (match_operand:DI 0 "s_register_operand" "=w")
1030 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
1031 (match_operand:DI 2 "s_register_operand" "w")]
1034 "vbic\t%P0, %P1, %P2"
1035 [(set_attr "neon_type" "neon_int_1")]
1038 (define_insn "xor<mode>3"
1039 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1040 (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
1041 (match_operand:VDQ 2 "s_register_operand" "w")))]
1043 "veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1044 [(set_attr "neon_type" "neon_int_1")]
1047 (define_insn "xordi3_neon"
1048 [(set (match_operand:DI 0 "s_register_operand" "=w")
1049 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
1050 (match_operand:DI 2 "s_register_operand" "w")]
1053 "veor\t%P0, %P1, %P2"
1054 [(set_attr "neon_type" "neon_int_1")]
1057 (define_insn "one_cmpl<mode>2"
1058 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1059 (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
1061 "vmvn\t%<V_reg>0, %<V_reg>1"
1062 [(set_attr "neon_type" "neon_int_1")]
1065 (define_insn "abs<mode>2"
1066 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1067 (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
1069 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
1070 [(set (attr "neon_type")
1071 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1072 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1073 (const_string "neon_fp_vadd_ddd_vabs_dd")
1074 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1075 (const_string "neon_int_3")))]
1078 (define_insn "neg<mode>2"
1079 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1080 (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
1082 "vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
1083 [(set (attr "neon_type")
1084 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1085 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1086 (const_string "neon_fp_vadd_ddd_vabs_dd")
1087 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1088 (const_string "neon_int_3")))]
1091 (define_insn "*umin<mode>3_neon"
1092 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1093 (umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1094 (match_operand:VDQIW 2 "s_register_operand" "w")))]
1096 "vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1097 [(set_attr "neon_type" "neon_int_5")]
1100 (define_insn "*umax<mode>3_neon"
1101 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1102 (umax:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1103 (match_operand:VDQIW 2 "s_register_operand" "w")))]
1105 "vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1106 [(set_attr "neon_type" "neon_int_5")]
1109 (define_insn "*smin<mode>3_neon"
1110 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1111 (smin:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
1112 (match_operand:VDQW 2 "s_register_operand" "w")))]
1114 "vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1115 [(set (attr "neon_type")
1116 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1117 (const_string "neon_fp_vadd_ddd_vabs_dd")
1118 (const_string "neon_int_5")))]
1121 (define_insn "*smax<mode>3_neon"
1122 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1123 (smax:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
1124 (match_operand:VDQW 2 "s_register_operand" "w")))]
1126 "vmax.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1127 [(set (attr "neon_type")
1128 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1129 (const_string "neon_fp_vadd_ddd_vabs_dd")
1130 (const_string "neon_int_5")))]
1133 ; TODO: V2DI shifts are current disabled because there are bugs in the
1134 ; generic vectorizer code. It ends up creating a V2DI constructor with
1137 (define_insn "vashl<mode>3"
1138 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1139 (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1140 (match_operand:VDQIW 2 "s_register_operand" "w")))]
1142 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1143 [(set (attr "neon_type")
1144 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1145 (const_string "neon_vshl_ddd")
1146 (const_string "neon_shift_3")))]
1149 ; Used for implementing logical shift-right, which is a left-shift by a negative
1150 ; amount, with signed operands. This is essentially the same as ashl<mode>3
1151 ; above, but using an unspec in case GCC tries anything tricky with negative
1154 (define_insn "ashl<mode>3_signed"
1155 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
1156 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
1157 (match_operand:VDQI 2 "s_register_operand" "w")]
1158 UNSPEC_ASHIFT_SIGNED))]
1160 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1161 [(set (attr "neon_type")
1162 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1163 (const_string "neon_vshl_ddd")
1164 (const_string "neon_shift_3")))]
1167 ; Used for implementing logical shift-right, which is a left-shift by a negative
1168 ; amount, with unsigned operands.
1170 (define_insn "ashl<mode>3_unsigned"
1171 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
1172 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
1173 (match_operand:VDQI 2 "s_register_operand" "w")]
1174 UNSPEC_ASHIFT_UNSIGNED))]
1176 "vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1177 [(set (attr "neon_type")
1178 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1179 (const_string "neon_vshl_ddd")
1180 (const_string "neon_shift_3")))]
1183 (define_expand "vashr<mode>3"
1184 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1185 (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1186 (match_operand:VDQIW 2 "s_register_operand" "")))]
1189 rtx neg = gen_reg_rtx (<MODE>mode);
1191 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1192 emit_insn (gen_ashl<mode>3_signed (operands[0], operands[1], neg));
1197 (define_expand "vlshr<mode>3"
1198 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1199 (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1200 (match_operand:VDQIW 2 "s_register_operand" "")))]
1203 rtx neg = gen_reg_rtx (<MODE>mode);
1205 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1206 emit_insn (gen_ashl<mode>3_unsigned (operands[0], operands[1], neg));
1211 ;; Widening operations
1213 (define_insn "widen_ssum<mode>3"
1214 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1215 (plus:<V_widen> (sign_extend:<V_widen>
1216 (match_operand:VW 1 "s_register_operand" "%w"))
1217 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1219 "vaddw.<V_s_elem>\t%q0, %q2, %P1"
1220 [(set_attr "neon_type" "neon_int_3")]
1223 (define_insn "widen_usum<mode>3"
1224 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1225 (plus:<V_widen> (zero_extend:<V_widen>
1226 (match_operand:VW 1 "s_register_operand" "%w"))
1227 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1229 "vaddw.<V_u_elem>\t%q0, %q2, %P1"
1230 [(set_attr "neon_type" "neon_int_3")]
1233 ;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
1234 ;; shift-count granularity. That's good enough for the middle-end's current
1237 (define_expand "vec_shr_<mode>"
1238 [(match_operand:VDQ 0 "s_register_operand" "")
1239 (match_operand:VDQ 1 "s_register_operand" "")
1240 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1244 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1245 const int width = GET_MODE_BITSIZE (<MODE>mode);
1246 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1247 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1248 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1250 if (num_bits == width)
1252 emit_move_insn (operands[0], operands[1]);
1256 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1257 operands[0] = gen_lowpart (bvecmode, operands[0]);
1258 operands[1] = gen_lowpart (bvecmode, operands[1]);
1260 emit_insn (gen_ext (operands[0], operands[1], zero_reg,
1261 GEN_INT (num_bits / BITS_PER_UNIT)));
1265 (define_expand "vec_shl_<mode>"
1266 [(match_operand:VDQ 0 "s_register_operand" "")
1267 (match_operand:VDQ 1 "s_register_operand" "")
1268 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1272 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1273 const int width = GET_MODE_BITSIZE (<MODE>mode);
1274 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1275 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1276 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1280 emit_move_insn (operands[0], CONST0_RTX (<MODE>mode));
1284 num_bits = width - num_bits;
1286 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1287 operands[0] = gen_lowpart (bvecmode, operands[0]);
1288 operands[1] = gen_lowpart (bvecmode, operands[1]);
1290 emit_insn (gen_ext (operands[0], zero_reg, operands[1],
1291 GEN_INT (num_bits / BITS_PER_UNIT)));
1295 ;; Helpers for quad-word reduction operations
1297 ; Add (or smin, smax...) the low N/2 elements of the N-element vector
1298 ; operand[1] to the high N/2 elements of same. Put the result in operand[0], an
1299 ; N/2-element vector.
1301 (define_insn "quad_halves_<code>v4si"
1302 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
1304 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
1305 (parallel [(const_int 0) (const_int 1)]))
1306 (vec_select:V2SI (match_dup 1)
1307 (parallel [(const_int 2) (const_int 3)]))))]
1309 "<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1"
1310 [(set_attr "vqh_mnem" "<VQH_mnem>")
1311 (set (attr "neon_type")
1312 (if_then_else (eq_attr "vqh_mnem" "vadd")
1313 (const_string "neon_int_1") (const_string "neon_int_5")))]
1316 (define_insn "quad_halves_<code>v4sf"
1317 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
1319 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
1320 (parallel [(const_int 0) (const_int 1)]))
1321 (vec_select:V2SF (match_dup 1)
1322 (parallel [(const_int 2) (const_int 3)]))))]
1324 "<VQH_mnem>.f32\t%P0, %e1, %f1"
1325 [(set_attr "vqh_mnem" "<VQH_mnem>")
1326 (set (attr "neon_type")
1327 (if_then_else (eq_attr "vqh_mnem" "vadd")
1328 (const_string "neon_int_1") (const_string "neon_int_5")))]
1331 (define_insn "quad_halves_<code>v8hi"
1332 [(set (match_operand:V4HI 0 "s_register_operand" "+w")
1334 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
1335 (parallel [(const_int 0) (const_int 1)
1336 (const_int 2) (const_int 3)]))
1337 (vec_select:V4HI (match_dup 1)
1338 (parallel [(const_int 4) (const_int 5)
1339 (const_int 6) (const_int 7)]))))]
1341 "<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1"
1342 [(set_attr "vqh_mnem" "<VQH_mnem>")
1343 (set (attr "neon_type")
1344 (if_then_else (eq_attr "vqh_mnem" "vadd")
1345 (const_string "neon_int_1") (const_string "neon_int_5")))]
1348 (define_insn "quad_halves_<code>v16qi"
1349 [(set (match_operand:V8QI 0 "s_register_operand" "+w")
1351 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
1352 (parallel [(const_int 0) (const_int 1)
1353 (const_int 2) (const_int 3)
1354 (const_int 4) (const_int 5)
1355 (const_int 6) (const_int 7)]))
1356 (vec_select:V8QI (match_dup 1)
1357 (parallel [(const_int 8) (const_int 9)
1358 (const_int 10) (const_int 11)
1359 (const_int 12) (const_int 13)
1360 (const_int 14) (const_int 15)]))))]
1362 "<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1"
1363 [(set_attr "vqh_mnem" "<VQH_mnem>")
1364 (set (attr "neon_type")
1365 (if_then_else (eq_attr "vqh_mnem" "vadd")
1366 (const_string "neon_int_1") (const_string "neon_int_5")))]
1369 ; FIXME: We wouldn't need the following insns if we could write subregs of
1370 ; vector registers. Make an attempt at removing unnecessary moves, though
1371 ; we're really at the mercy of the register allocator.
1373 (define_insn "move_lo_quad_v4si"
1374 [(set (match_operand:V4SI 0 "s_register_operand" "+w")
1376 (match_operand:V2SI 1 "s_register_operand" "w")
1377 (vec_select:V2SI (match_dup 0)
1378 (parallel [(const_int 2) (const_int 3)]))))]
1381 int dest = REGNO (operands[0]);
1382 int src = REGNO (operands[1]);
1385 return "vmov\t%e0, %P1";
1389 [(set_attr "neon_type" "neon_bp_simple")]
1392 (define_insn "move_lo_quad_v4sf"
1393 [(set (match_operand:V4SF 0 "s_register_operand" "+w")
1395 (match_operand:V2SF 1 "s_register_operand" "w")
1396 (vec_select:V2SF (match_dup 0)
1397 (parallel [(const_int 2) (const_int 3)]))))]
1400 int dest = REGNO (operands[0]);
1401 int src = REGNO (operands[1]);
1404 return "vmov\t%e0, %P1";
1408 [(set_attr "neon_type" "neon_bp_simple")]
1411 (define_insn "move_lo_quad_v8hi"
1412 [(set (match_operand:V8HI 0 "s_register_operand" "+w")
1414 (match_operand:V4HI 1 "s_register_operand" "w")
1415 (vec_select:V4HI (match_dup 0)
1416 (parallel [(const_int 4) (const_int 5)
1417 (const_int 6) (const_int 7)]))))]
1420 int dest = REGNO (operands[0]);
1421 int src = REGNO (operands[1]);
1424 return "vmov\t%e0, %P1";
1428 [(set_attr "neon_type" "neon_bp_simple")]
1431 (define_insn "move_lo_quad_v16qi"
1432 [(set (match_operand:V16QI 0 "s_register_operand" "+w")
1434 (match_operand:V8QI 1 "s_register_operand" "w")
1435 (vec_select:V8QI (match_dup 0)
1436 (parallel [(const_int 8) (const_int 9)
1437 (const_int 10) (const_int 11)
1438 (const_int 12) (const_int 13)
1439 (const_int 14) (const_int 15)]))))]
1442 int dest = REGNO (operands[0]);
1443 int src = REGNO (operands[1]);
1446 return "vmov\t%e0, %P1";
1450 [(set_attr "neon_type" "neon_bp_simple")]
1453 ;; Reduction operations
1455 (define_expand "reduc_splus_<mode>"
1456 [(match_operand:VD 0 "s_register_operand" "")
1457 (match_operand:VD 1 "s_register_operand" "")]
1460 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1461 &gen_neon_vpadd_internal<mode>);
1465 (define_expand "reduc_splus_<mode>"
1466 [(match_operand:VQ 0 "s_register_operand" "")
1467 (match_operand:VQ 1 "s_register_operand" "")]
1470 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1471 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1473 emit_insn (gen_quad_halves_plus<mode> (step1, operands[1]));
1474 emit_insn (gen_reduc_splus_<V_half> (res_d, step1));
1475 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1480 (define_insn "reduc_splus_v2di"
1481 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1482 (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")]
1485 "vadd.i64\t%e0, %e1, %f1"
1486 [(set_attr "neon_type" "neon_int_1")]
1489 ;; NEON does not distinguish between signed and unsigned addition except on
1490 ;; widening operations.
1491 (define_expand "reduc_uplus_<mode>"
1492 [(match_operand:VDQI 0 "s_register_operand" "")
1493 (match_operand:VDQI 1 "s_register_operand" "")]
1496 emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1]));
1500 (define_expand "reduc_smin_<mode>"
1501 [(match_operand:VD 0 "s_register_operand" "")
1502 (match_operand:VD 1 "s_register_operand" "")]
1505 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1506 &gen_neon_vpsmin<mode>);
1510 (define_expand "reduc_smin_<mode>"
1511 [(match_operand:VQ 0 "s_register_operand" "")
1512 (match_operand:VQ 1 "s_register_operand" "")]
1515 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1516 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1518 emit_insn (gen_quad_halves_smin<mode> (step1, operands[1]));
1519 emit_insn (gen_reduc_smin_<V_half> (res_d, step1));
1520 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1525 (define_expand "reduc_smax_<mode>"
1526 [(match_operand:VD 0 "s_register_operand" "")
1527 (match_operand:VD 1 "s_register_operand" "")]
1530 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1531 &gen_neon_vpsmax<mode>);
1535 (define_expand "reduc_smax_<mode>"
1536 [(match_operand:VQ 0 "s_register_operand" "")
1537 (match_operand:VQ 1 "s_register_operand" "")]
1540 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1541 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1543 emit_insn (gen_quad_halves_smax<mode> (step1, operands[1]));
1544 emit_insn (gen_reduc_smax_<V_half> (res_d, step1));
1545 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1550 (define_expand "reduc_umin_<mode>"
1551 [(match_operand:VDI 0 "s_register_operand" "")
1552 (match_operand:VDI 1 "s_register_operand" "")]
1555 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1556 &gen_neon_vpumin<mode>);
1560 (define_expand "reduc_umin_<mode>"
1561 [(match_operand:VQI 0 "s_register_operand" "")
1562 (match_operand:VQI 1 "s_register_operand" "")]
1565 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1566 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1568 emit_insn (gen_quad_halves_umin<mode> (step1, operands[1]));
1569 emit_insn (gen_reduc_umin_<V_half> (res_d, step1));
1570 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1575 (define_expand "reduc_umax_<mode>"
1576 [(match_operand:VDI 0 "s_register_operand" "")
1577 (match_operand:VDI 1 "s_register_operand" "")]
1580 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1581 &gen_neon_vpumax<mode>);
1585 (define_expand "reduc_umax_<mode>"
1586 [(match_operand:VQI 0 "s_register_operand" "")
1587 (match_operand:VQI 1 "s_register_operand" "")]
1590 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1591 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1593 emit_insn (gen_quad_halves_umax<mode> (step1, operands[1]));
1594 emit_insn (gen_reduc_umax_<V_half> (res_d, step1));
1595 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1600 (define_insn "neon_vpadd_internal<mode>"
1601 [(set (match_operand:VD 0 "s_register_operand" "=w")
1602 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1603 (match_operand:VD 2 "s_register_operand" "w")]
1606 "vpadd.<V_if_elem>\t%P0, %P1, %P2"
1607 ;; Assume this schedules like vadd.
1608 [(set (attr "neon_type")
1609 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1610 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1611 (const_string "neon_fp_vadd_ddd_vabs_dd")
1612 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1613 (const_string "neon_int_1")))]
1616 (define_insn "neon_vpsmin<mode>"
1617 [(set (match_operand:VD 0 "s_register_operand" "=w")
1618 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1619 (match_operand:VD 2 "s_register_operand" "w")]
1622 "vpmin.<V_s_elem>\t%P0, %P1, %P2"
1623 ;; Assume this schedules like vmin.
1624 [(set (attr "neon_type")
1625 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1626 (const_string "neon_fp_vadd_ddd_vabs_dd")
1627 (const_string "neon_int_5")))]
1630 (define_insn "neon_vpsmax<mode>"
1631 [(set (match_operand:VD 0 "s_register_operand" "=w")
1632 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1633 (match_operand:VD 2 "s_register_operand" "w")]
1636 "vpmax.<V_s_elem>\t%P0, %P1, %P2"
1637 ;; Assume this schedules like vmax.
1638 [(set (attr "neon_type")
1639 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1640 (const_string "neon_fp_vadd_ddd_vabs_dd")
1641 (const_string "neon_int_5")))]
1644 (define_insn "neon_vpumin<mode>"
1645 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1646 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1647 (match_operand:VDI 2 "s_register_operand" "w")]
1650 "vpmin.<V_u_elem>\t%P0, %P1, %P2"
1651 ;; Assume this schedules like umin.
1652 [(set_attr "neon_type" "neon_int_5")]
1655 (define_insn "neon_vpumax<mode>"
1656 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1657 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1658 (match_operand:VDI 2 "s_register_operand" "w")]
1661 "vpmax.<V_u_elem>\t%P0, %P1, %P2"
1662 ;; Assume this schedules like umax.
1663 [(set_attr "neon_type" "neon_int_5")]
1666 ;; Saturating arithmetic
1668 ; NOTE: Neon supports many more saturating variants of instructions than the
1669 ; following, but these are all GCC currently understands.
1670 ; FIXME: Actually, GCC doesn't know how to create saturating add/sub by itself
1671 ; yet either, although these patterns may be used by intrinsics when they're
1674 (define_insn "*ss_add<mode>_neon"
1675 [(set (match_operand:VD 0 "s_register_operand" "=w")
1676 (ss_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1677 (match_operand:VD 2 "s_register_operand" "w")))]
1679 "vqadd.<V_s_elem>\t%P0, %P1, %P2"
1680 [(set_attr "neon_type" "neon_int_4")]
1683 (define_insn "*us_add<mode>_neon"
1684 [(set (match_operand:VD 0 "s_register_operand" "=w")
1685 (us_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1686 (match_operand:VD 2 "s_register_operand" "w")))]
1688 "vqadd.<V_u_elem>\t%P0, %P1, %P2"
1689 [(set_attr "neon_type" "neon_int_4")]
1692 (define_insn "*ss_sub<mode>_neon"
1693 [(set (match_operand:VD 0 "s_register_operand" "=w")
1694 (ss_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1695 (match_operand:VD 2 "s_register_operand" "w")))]
1697 "vqsub.<V_s_elem>\t%P0, %P1, %P2"
1698 [(set_attr "neon_type" "neon_int_5")]
1701 (define_insn "*us_sub<mode>_neon"
1702 [(set (match_operand:VD 0 "s_register_operand" "=w")
1703 (us_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1704 (match_operand:VD 2 "s_register_operand" "w")))]
1706 "vqsub.<V_u_elem>\t%P0, %P1, %P2"
1707 [(set_attr "neon_type" "neon_int_5")]
1710 ;; Patterns for builtins.
1712 ; good for plain vadd, vaddq.
1714 (define_insn "neon_vadd<mode>"
1715 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1716 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1717 (match_operand:VDQX 2 "s_register_operand" "w")
1718 (match_operand:SI 3 "immediate_operand" "i")]
1721 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1722 [(set (attr "neon_type")
1723 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1724 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1725 (const_string "neon_fp_vadd_ddd_vabs_dd")
1726 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1727 (const_string "neon_int_1")))]
1730 ; operand 3 represents in bits:
1731 ; bit 0: signed (vs unsigned).
1732 ; bit 1: rounding (vs none).
1734 (define_insn "neon_vaddl<mode>"
1735 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1736 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1737 (match_operand:VDI 2 "s_register_operand" "w")
1738 (match_operand:SI 3 "immediate_operand" "i")]
1741 "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1742 [(set_attr "neon_type" "neon_int_3")]
1745 (define_insn "neon_vaddw<mode>"
1746 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1747 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1748 (match_operand:VDI 2 "s_register_operand" "w")
1749 (match_operand:SI 3 "immediate_operand" "i")]
1752 "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
1753 [(set_attr "neon_type" "neon_int_2")]
1758 (define_insn "neon_vhadd<mode>"
1759 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1760 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1761 (match_operand:VDQIW 2 "s_register_operand" "w")
1762 (match_operand:SI 3 "immediate_operand" "i")]
1765 "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1766 [(set_attr "neon_type" "neon_int_4")]
1769 (define_insn "neon_vqadd<mode>"
1770 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1771 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1772 (match_operand:VDQIX 2 "s_register_operand" "w")
1773 (match_operand:SI 3 "immediate_operand" "i")]
1776 "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1777 [(set_attr "neon_type" "neon_int_4")]
1780 (define_insn "neon_vaddhn<mode>"
1781 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
1782 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
1783 (match_operand:VN 2 "s_register_operand" "w")
1784 (match_operand:SI 3 "immediate_operand" "i")]
1787 "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2"
1788 [(set_attr "neon_type" "neon_int_4")]
1791 (define_insn "neon_vmul<mode>"
1792 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1793 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1794 (match_operand:VDQW 2 "s_register_operand" "w")
1795 (match_operand:SI 3 "immediate_operand" "i")]
1798 "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1799 [(set (attr "neon_type")
1800 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1801 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1802 (const_string "neon_fp_vadd_ddd_vabs_dd")
1803 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1804 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1806 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1807 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1808 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1809 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1810 (const_string "neon_mul_qqq_8_16_32_ddd_32")
1811 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
1814 (define_insn "neon_vmla<mode>"
1815 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1816 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
1817 (match_operand:VDQW 2 "s_register_operand" "w")
1818 (match_operand:VDQW 3 "s_register_operand" "w")
1819 (match_operand:SI 4 "immediate_operand" "i")]
1822 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
1823 [(set (attr "neon_type")
1824 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1825 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1826 (const_string "neon_fp_vmla_ddd")
1827 (const_string "neon_fp_vmla_qqq"))
1828 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1830 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1831 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1832 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1833 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1834 (const_string "neon_mla_qqq_8_16")
1835 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1838 (define_insn "neon_vmlal<mode>"
1839 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1840 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1841 (match_operand:VW 2 "s_register_operand" "w")
1842 (match_operand:VW 3 "s_register_operand" "w")
1843 (match_operand:SI 4 "immediate_operand" "i")]
1846 "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
1847 [(set (attr "neon_type")
1848 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1849 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1850 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1853 (define_insn "neon_vmls<mode>"
1854 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1855 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
1856 (match_operand:VDQW 2 "s_register_operand" "w")
1857 (match_operand:VDQW 3 "s_register_operand" "w")
1858 (match_operand:SI 4 "immediate_operand" "i")]
1861 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
1862 [(set (attr "neon_type")
1863 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1864 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1865 (const_string "neon_fp_vmla_ddd")
1866 (const_string "neon_fp_vmla_qqq"))
1867 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1869 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1870 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1871 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1873 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1874 (const_string "neon_mla_qqq_8_16")
1875 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1878 (define_insn "neon_vmlsl<mode>"
1879 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1880 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1881 (match_operand:VW 2 "s_register_operand" "w")
1882 (match_operand:VW 3 "s_register_operand" "w")
1883 (match_operand:SI 4 "immediate_operand" "i")]
1886 "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
1887 [(set (attr "neon_type")
1888 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1889 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1890 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1893 (define_insn "neon_vqdmulh<mode>"
1894 [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
1895 (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
1896 (match_operand:VMDQI 2 "s_register_operand" "w")
1897 (match_operand:SI 3 "immediate_operand" "i")]
1900 "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1901 [(set (attr "neon_type")
1902 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1903 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1904 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1905 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1906 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1907 (const_string "neon_mul_qqq_8_16_32_ddd_32")
1908 (const_string "neon_mul_qqq_8_16_32_ddd_32"))))]
1911 (define_insn "neon_vqdmlal<mode>"
1912 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1913 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1914 (match_operand:VMDI 2 "s_register_operand" "w")
1915 (match_operand:VMDI 3 "s_register_operand" "w")
1916 (match_operand:SI 4 "immediate_operand" "i")]
1919 "vqdmlal.<V_s_elem>\t%q0, %P2, %P3"
1920 [(set (attr "neon_type")
1921 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1922 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1923 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1926 (define_insn "neon_vqdmlsl<mode>"
1927 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1928 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1929 (match_operand:VMDI 2 "s_register_operand" "w")
1930 (match_operand:VMDI 3 "s_register_operand" "w")
1931 (match_operand:SI 4 "immediate_operand" "i")]
1934 "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3"
1935 [(set (attr "neon_type")
1936 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1937 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1938 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1941 (define_insn "neon_vmull<mode>"
1942 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1943 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
1944 (match_operand:VW 2 "s_register_operand" "w")
1945 (match_operand:SI 3 "immediate_operand" "i")]
1948 "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1949 [(set (attr "neon_type")
1950 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1951 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1952 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1955 (define_insn "neon_vqdmull<mode>"
1956 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1957 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
1958 (match_operand:VMDI 2 "s_register_operand" "w")
1959 (match_operand:SI 3 "immediate_operand" "i")]
1962 "vqdmull.<V_s_elem>\t%q0, %P1, %P2"
1963 [(set (attr "neon_type")
1964 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1965 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1966 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1969 (define_insn "neon_vsub<mode>"
1970 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1971 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1972 (match_operand:VDQX 2 "s_register_operand" "w")
1973 (match_operand:SI 3 "immediate_operand" "i")]
1976 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1977 [(set (attr "neon_type")
1978 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1979 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1980 (const_string "neon_fp_vadd_ddd_vabs_dd")
1981 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1982 (const_string "neon_int_2")))]
1985 (define_insn "neon_vsubl<mode>"
1986 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1987 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1988 (match_operand:VDI 2 "s_register_operand" "w")
1989 (match_operand:SI 3 "immediate_operand" "i")]
1992 "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1993 [(set_attr "neon_type" "neon_int_2")]
1996 (define_insn "neon_vsubw<mode>"
1997 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1998 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1999 (match_operand:VDI 2 "s_register_operand" "w")
2000 (match_operand:SI 3 "immediate_operand" "i")]
2003 "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
2004 [(set_attr "neon_type" "neon_int_2")]
2007 (define_insn "neon_vqsub<mode>"
2008 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2009 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2010 (match_operand:VDQIX 2 "s_register_operand" "w")
2011 (match_operand:SI 3 "immediate_operand" "i")]
2014 "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2015 [(set_attr "neon_type" "neon_int_5")]
2018 (define_insn "neon_vhsub<mode>"
2019 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2020 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2021 (match_operand:VDQIW 2 "s_register_operand" "w")
2022 (match_operand:SI 3 "immediate_operand" "i")]
2025 "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2026 [(set_attr "neon_type" "neon_int_5")]
2029 (define_insn "neon_vsubhn<mode>"
2030 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2031 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2032 (match_operand:VN 2 "s_register_operand" "w")
2033 (match_operand:SI 3 "immediate_operand" "i")]
2036 "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2"
2037 [(set_attr "neon_type" "neon_int_4")]
2040 (define_insn "neon_vceq<mode>"
2041 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2042 (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
2043 (match_operand:VDQW 2 "s_register_operand" "w")
2044 (match_operand:SI 3 "immediate_operand" "i")]
2047 "vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2048 [(set (attr "neon_type")
2049 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2050 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2051 (const_string "neon_fp_vadd_ddd_vabs_dd")
2052 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2053 (const_string "neon_int_5")))]
2056 (define_insn "neon_vcge<mode>"
2057 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2058 (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
2059 (match_operand:VDQW 2 "s_register_operand" "w")
2060 (match_operand:SI 3 "immediate_operand" "i")]
2063 "vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2064 [(set (attr "neon_type")
2065 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2066 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2067 (const_string "neon_fp_vadd_ddd_vabs_dd")
2068 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2069 (const_string "neon_int_5")))]
2072 (define_insn "neon_vcgt<mode>"
2073 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2074 (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
2075 (match_operand:VDQW 2 "s_register_operand" "w")
2076 (match_operand:SI 3 "immediate_operand" "i")]
2079 "vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2080 [(set (attr "neon_type")
2081 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2082 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2083 (const_string "neon_fp_vadd_ddd_vabs_dd")
2084 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2085 (const_string "neon_int_5")))]
2088 (define_insn "neon_vcage<mode>"
2089 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2090 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2091 (match_operand:VCVTF 2 "s_register_operand" "w")
2092 (match_operand:SI 3 "immediate_operand" "i")]
2095 "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2096 [(set (attr "neon_type")
2097 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2098 (const_string "neon_fp_vadd_ddd_vabs_dd")
2099 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2102 (define_insn "neon_vcagt<mode>"
2103 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2104 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2105 (match_operand:VCVTF 2 "s_register_operand" "w")
2106 (match_operand:SI 3 "immediate_operand" "i")]
2109 "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2110 [(set (attr "neon_type")
2111 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2112 (const_string "neon_fp_vadd_ddd_vabs_dd")
2113 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2116 (define_insn "neon_vtst<mode>"
2117 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2118 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2119 (match_operand:VDQIW 2 "s_register_operand" "w")
2120 (match_operand:SI 3 "immediate_operand" "i")]
2123 "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2124 [(set_attr "neon_type" "neon_int_4")]
2127 (define_insn "neon_vabd<mode>"
2128 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2129 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2130 (match_operand:VDQW 2 "s_register_operand" "w")
2131 (match_operand:SI 3 "immediate_operand" "i")]
2134 "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2135 [(set (attr "neon_type")
2136 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2137 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2138 (const_string "neon_fp_vadd_ddd_vabs_dd")
2139 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2140 (const_string "neon_int_5")))]
2143 (define_insn "neon_vabdl<mode>"
2144 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2145 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2146 (match_operand:VW 2 "s_register_operand" "w")
2147 (match_operand:SI 3 "immediate_operand" "i")]
2150 "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2151 [(set_attr "neon_type" "neon_int_5")]
2154 (define_insn "neon_vaba<mode>"
2155 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2156 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "0")
2157 (match_operand:VDQIW 2 "s_register_operand" "w")
2158 (match_operand:VDQIW 3 "s_register_operand" "w")
2159 (match_operand:SI 4 "immediate_operand" "i")]
2162 "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2163 [(set (attr "neon_type")
2164 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2165 (const_string "neon_vaba") (const_string "neon_vaba_qqq")))]
2168 (define_insn "neon_vabal<mode>"
2169 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2170 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2171 (match_operand:VW 2 "s_register_operand" "w")
2172 (match_operand:VW 3 "s_register_operand" "w")
2173 (match_operand:SI 4 "immediate_operand" "i")]
2176 "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2177 [(set_attr "neon_type" "neon_vaba")]
2180 (define_insn "neon_vmax<mode>"
2181 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2182 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2183 (match_operand:VDQW 2 "s_register_operand" "w")
2184 (match_operand:SI 3 "immediate_operand" "i")]
2187 "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2188 [(set (attr "neon_type")
2189 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2190 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2191 (const_string "neon_fp_vadd_ddd_vabs_dd")
2192 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2193 (const_string "neon_int_5")))]
2196 (define_insn "neon_vmin<mode>"
2197 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2198 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2199 (match_operand:VDQW 2 "s_register_operand" "w")
2200 (match_operand:SI 3 "immediate_operand" "i")]
2203 "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2204 [(set (attr "neon_type")
2205 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2206 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2207 (const_string "neon_fp_vadd_ddd_vabs_dd")
2208 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2209 (const_string "neon_int_5")))]
2212 (define_expand "neon_vpadd<mode>"
2213 [(match_operand:VD 0 "s_register_operand" "=w")
2214 (match_operand:VD 1 "s_register_operand" "w")
2215 (match_operand:VD 2 "s_register_operand" "w")
2216 (match_operand:SI 3 "immediate_operand" "i")]
2219 emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1],
2224 (define_insn "neon_vpaddl<mode>"
2225 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2226 (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")
2227 (match_operand:SI 2 "immediate_operand" "i")]
2230 "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2231 ;; Assume this schedules like vaddl.
2232 [(set_attr "neon_type" "neon_int_3")]
2235 (define_insn "neon_vpadal<mode>"
2236 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2237 (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0")
2238 (match_operand:VDQIW 2 "s_register_operand" "w")
2239 (match_operand:SI 3 "immediate_operand" "i")]
2242 "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
2243 ;; Assume this schedules like vpadd.
2244 [(set_attr "neon_type" "neon_int_1")]
2247 (define_insn "neon_vpmax<mode>"
2248 [(set (match_operand:VD 0 "s_register_operand" "=w")
2249 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2250 (match_operand:VD 2 "s_register_operand" "w")
2251 (match_operand:SI 3 "immediate_operand" "i")]
2254 "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2255 ;; Assume this schedules like vmax.
2256 [(set (attr "neon_type")
2257 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2258 (const_string "neon_fp_vadd_ddd_vabs_dd")
2259 (const_string "neon_int_5")))]
2262 (define_insn "neon_vpmin<mode>"
2263 [(set (match_operand:VD 0 "s_register_operand" "=w")
2264 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2265 (match_operand:VD 2 "s_register_operand" "w")
2266 (match_operand:SI 3 "immediate_operand" "i")]
2269 "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2270 ;; Assume this schedules like vmin.
2271 [(set (attr "neon_type")
2272 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2273 (const_string "neon_fp_vadd_ddd_vabs_dd")
2274 (const_string "neon_int_5")))]
2277 (define_insn "neon_vrecps<mode>"
2278 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2279 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2280 (match_operand:VCVTF 2 "s_register_operand" "w")
2281 (match_operand:SI 3 "immediate_operand" "i")]
2284 "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2285 [(set (attr "neon_type")
2286 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2287 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2288 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2291 (define_insn "neon_vrsqrts<mode>"
2292 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2293 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2294 (match_operand:VCVTF 2 "s_register_operand" "w")
2295 (match_operand:SI 3 "immediate_operand" "i")]
2298 "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2299 [(set (attr "neon_type")
2300 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2301 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2302 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2305 (define_insn "neon_vabs<mode>"
2306 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2307 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2308 (match_operand:SI 2 "immediate_operand" "i")]
2311 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2312 [(set (attr "neon_type")
2313 (if_then_else (ior (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2314 (ne (symbol_ref "<Is_float_mode>") (const_int 0)))
2316 (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2317 (const_string "neon_fp_vadd_ddd_vabs_dd")
2318 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2319 (const_string "neon_vqneg_vqabs")))]
2322 (define_insn "neon_vqabs<mode>"
2323 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2324 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2325 (match_operand:SI 2 "immediate_operand" "i")]
2328 "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2329 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2332 (define_expand "neon_vneg<mode>"
2333 [(match_operand:VDQW 0 "s_register_operand" "")
2334 (match_operand:VDQW 1 "s_register_operand" "")
2335 (match_operand:SI 2 "immediate_operand" "")]
2338 emit_insn (gen_neg<mode>2 (operands[0], operands[1]));
2342 (define_insn "neon_vqneg<mode>"
2343 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2344 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2345 (match_operand:SI 2 "immediate_operand" "i")]
2348 "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2349 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2352 (define_insn "neon_vcls<mode>"
2353 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2354 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2355 (match_operand:SI 2 "immediate_operand" "i")]
2358 "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2359 [(set_attr "neon_type" "neon_int_1")]
2362 (define_insn "neon_vclz<mode>"
2363 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2364 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2365 (match_operand:SI 2 "immediate_operand" "i")]
2368 "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1"
2369 [(set_attr "neon_type" "neon_int_1")]
2372 (define_insn "neon_vcnt<mode>"
2373 [(set (match_operand:VE 0 "s_register_operand" "=w")
2374 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
2375 (match_operand:SI 2 "immediate_operand" "i")]
2378 "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2379 [(set_attr "neon_type" "neon_int_1")]
2382 (define_insn "neon_vrecpe<mode>"
2383 [(set (match_operand:V32 0 "s_register_operand" "=w")
2384 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2385 (match_operand:SI 2 "immediate_operand" "i")]
2388 "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2389 [(set (attr "neon_type")
2390 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2391 (const_string "neon_fp_vadd_ddd_vabs_dd")
2392 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2395 (define_insn "neon_vrsqrte<mode>"
2396 [(set (match_operand:V32 0 "s_register_operand" "=w")
2397 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2398 (match_operand:SI 2 "immediate_operand" "i")]
2401 "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2402 [(set (attr "neon_type")
2403 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2404 (const_string "neon_fp_vadd_ddd_vabs_dd")
2405 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2408 (define_expand "neon_vmvn<mode>"
2409 [(match_operand:VDQIW 0 "s_register_operand" "")
2410 (match_operand:VDQIW 1 "s_register_operand" "")
2411 (match_operand:SI 2 "immediate_operand" "")]
2414 emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1]));
2418 (define_insn "neon_vget_lane<mode>_sext_internal"
2419 [(set (match_operand:SI 0 "s_register_operand" "=r")
2421 (vec_select:<V_elem>
2422 (match_operand:VD 1 "s_register_operand" "w")
2423 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2426 if (BYTES_BIG_ENDIAN)
2428 int elt = INTVAL (operands[2]);
2429 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2430 operands[2] = GEN_INT (elt);
2432 return "vmov%?.s<V_sz_elem>\t%0, %P1[%c2]";
2434 [(set_attr "predicable" "yes")
2435 (set_attr "neon_type" "neon_bp_simple")]
2438 (define_insn "neon_vget_lane<mode>_zext_internal"
2439 [(set (match_operand:SI 0 "s_register_operand" "=r")
2441 (vec_select:<V_elem>
2442 (match_operand:VD 1 "s_register_operand" "w")
2443 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2446 if (BYTES_BIG_ENDIAN)
2448 int elt = INTVAL (operands[2]);
2449 elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2450 operands[2] = GEN_INT (elt);
2452 return "vmov%?.u<V_sz_elem>\t%0, %P1[%c2]";
2454 [(set_attr "predicable" "yes")
2455 (set_attr "neon_type" "neon_bp_simple")]
2458 (define_insn "neon_vget_lane<mode>_sext_internal"
2459 [(set (match_operand:SI 0 "s_register_operand" "=r")
2461 (vec_select:<V_elem>
2462 (match_operand:VQ 1 "s_register_operand" "w")
2463 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2467 int regno = REGNO (operands[1]);
2468 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2469 unsigned int elt = INTVAL (operands[2]);
2470 unsigned int elt_adj = elt % halfelts;
2472 if (BYTES_BIG_ENDIAN)
2473 elt_adj = halfelts - 1 - elt_adj;
2475 ops[0] = operands[0];
2476 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2477 ops[2] = GEN_INT (elt_adj);
2478 output_asm_insn ("vmov%?.s<V_sz_elem>\t%0, %P1[%c2]", ops);
2482 [(set_attr "predicable" "yes")
2483 (set_attr "neon_type" "neon_bp_simple")]
2486 (define_insn "neon_vget_lane<mode>_zext_internal"
2487 [(set (match_operand:SI 0 "s_register_operand" "=r")
2489 (vec_select:<V_elem>
2490 (match_operand:VQ 1 "s_register_operand" "w")
2491 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2495 int regno = REGNO (operands[1]);
2496 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2497 unsigned int elt = INTVAL (operands[2]);
2498 unsigned int elt_adj = elt % halfelts;
2500 if (BYTES_BIG_ENDIAN)
2501 elt_adj = halfelts - 1 - elt_adj;
2503 ops[0] = operands[0];
2504 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2505 ops[2] = GEN_INT (elt_adj);
2506 output_asm_insn ("vmov%?.u<V_sz_elem>\t%0, %P1[%c2]", ops);
2510 [(set_attr "predicable" "yes")
2511 (set_attr "neon_type" "neon_bp_simple")]
2514 (define_expand "neon_vget_lane<mode>"
2515 [(match_operand:<V_ext> 0 "s_register_operand" "")
2516 (match_operand:VDQW 1 "s_register_operand" "")
2517 (match_operand:SI 2 "immediate_operand" "")
2518 (match_operand:SI 3 "immediate_operand" "")]
2521 HOST_WIDE_INT magic = INTVAL (operands[3]);
2524 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode));
2526 if (BYTES_BIG_ENDIAN)
2528 /* The intrinsics are defined in terms of a model where the
2529 element ordering in memory is vldm order, whereas the generic
2530 RTL is defined in terms of a model where the element ordering
2531 in memory is array order. Convert the lane number to conform
2533 unsigned int elt = INTVAL (operands[2]);
2534 unsigned int reg_nelts
2535 = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2536 elt ^= reg_nelts - 1;
2537 operands[2] = GEN_INT (elt);
2540 if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32)
2541 insn = gen_vec_extract<mode> (operands[0], operands[1], operands[2]);
2544 if ((magic & 1) != 0)
2545 insn = gen_neon_vget_lane<mode>_sext_internal (operands[0], operands[1],
2548 insn = gen_neon_vget_lane<mode>_zext_internal (operands[0], operands[1],
2555 ; Operand 3 (info word) is ignored because it does nothing useful with 64-bit
2558 (define_insn "neon_vget_lanedi"
2559 [(set (match_operand:DI 0 "s_register_operand" "=r")
2560 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
2561 (match_operand:SI 2 "immediate_operand" "i")
2562 (match_operand:SI 3 "immediate_operand" "i")]
2566 neon_lane_bounds (operands[2], 0, 1);
2567 return "vmov%?\t%Q0, %R0, %P1 @ di";
2569 [(set_attr "predicable" "yes")
2570 (set_attr "neon_type" "neon_bp_simple")]
2573 (define_insn "neon_vget_lanev2di"
2574 [(set (match_operand:DI 0 "s_register_operand" "=r")
2575 (unspec:DI [(match_operand:V2DI 1 "s_register_operand" "w")
2576 (match_operand:SI 2 "immediate_operand" "i")
2577 (match_operand:SI 3 "immediate_operand" "i")]
2582 unsigned int regno = REGNO (operands[1]);
2583 unsigned int elt = INTVAL (operands[2]);
2585 neon_lane_bounds (operands[2], 0, 2);
2587 ops[0] = operands[0];
2588 ops[1] = gen_rtx_REG (DImode, regno + 2 * elt);
2589 output_asm_insn ("vmov%?\t%Q0, %R0, %P1 @ v2di", ops);
2593 [(set_attr "predicable" "yes")
2594 (set_attr "neon_type" "neon_bp_simple")]
2597 (define_insn "neon_vset_lane<mode>"
2598 [(set (match_operand:VD 0 "s_register_operand" "=w")
2599 (unspec:VD [(match_operand:<V_elem> 1 "s_register_operand" "r")
2600 (match_operand:VD 2 "s_register_operand" "0")
2601 (match_operand:SI 3 "immediate_operand" "i")]
2605 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
2606 return "vmov%?.<V_sz_elem>\t%P0[%c3], %1";
2608 [(set_attr "predicable" "yes")
2609 (set_attr "neon_type" "neon_bp_simple")]
2612 ; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
2614 (define_insn "neon_vset_lanedi"
2615 [(set (match_operand:DI 0 "s_register_operand" "=w")
2616 (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")
2617 (match_operand:DI 2 "s_register_operand" "0")
2618 (match_operand:SI 3 "immediate_operand" "i")]
2622 neon_lane_bounds (operands[3], 0, 1);
2623 return "vmov%?\t%P0, %Q1, %R1 @ di";
2625 [(set_attr "predicable" "yes")
2626 (set_attr "neon_type" "neon_bp_simple")]
2629 (define_insn "neon_vset_lane<mode>"
2630 [(set (match_operand:VQ 0 "s_register_operand" "=w")
2631 (unspec:VQ [(match_operand:<V_elem> 1 "s_register_operand" "r")
2632 (match_operand:VQ 2 "s_register_operand" "0")
2633 (match_operand:SI 3 "immediate_operand" "i")]
2638 unsigned int regno = REGNO (operands[0]);
2639 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2640 unsigned int elt = INTVAL (operands[3]);
2642 neon_lane_bounds (operands[3], 0, halfelts * 2);
2644 ops[0] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2645 ops[1] = operands[1];
2646 ops[2] = GEN_INT (elt % halfelts);
2647 output_asm_insn ("vmov%?.<V_sz_elem>\t%P0[%c2], %1", ops);
2651 [(set_attr "predicable" "yes")
2652 (set_attr "neon_type" "neon_bp_simple")]
2655 (define_insn "neon_vset_lanev2di"
2656 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2657 (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "r")
2658 (match_operand:V2DI 2 "s_register_operand" "0")
2659 (match_operand:SI 3 "immediate_operand" "i")]
2664 unsigned int regno = REGNO (operands[0]);
2665 unsigned int elt = INTVAL (operands[3]);
2667 neon_lane_bounds (operands[3], 0, 2);
2669 ops[0] = gen_rtx_REG (DImode, regno + 2 * elt);
2670 ops[1] = operands[1];
2671 output_asm_insn ("vmov%?\t%P0, %Q1, %R1 @ v2di", ops);
2675 [(set_attr "predicable" "yes")
2676 (set_attr "neon_type" "neon_bp_simple")]
2679 (define_expand "neon_vcreate<mode>"
2680 [(match_operand:VDX 0 "s_register_operand" "")
2681 (match_operand:DI 1 "general_operand" "")]
2684 rtx src = gen_lowpart (<MODE>mode, operands[1]);
2685 emit_move_insn (operands[0], src);
2689 (define_insn "neon_vdup_n<mode>"
2690 [(set (match_operand:VX 0 "s_register_operand" "=w")
2691 (unspec:VX [(match_operand:<V_elem> 1 "s_register_operand" "r")]
2694 "vdup%?.<V_sz_elem>\t%<V_reg>0, %1"
2695 ;; Assume this schedules like vmov.
2696 [(set_attr "predicable" "yes")
2697 (set_attr "neon_type" "neon_bp_simple")]
2700 (define_insn "neon_vdup_n<mode>"
2701 [(set (match_operand:V32 0 "s_register_operand" "=w,w")
2702 (unspec:V32 [(match_operand:<V_elem> 1 "s_register_operand" "r,t")]
2706 vdup%?.<V_sz_elem>\t%<V_reg>0, %1
2707 vdup%?.<V_sz_elem>\t%<V_reg>0, %y1"
2708 ;; Assume this schedules like vmov.
2709 [(set_attr "predicable" "yes")
2710 (set_attr "neon_type" "neon_bp_simple")]
2713 (define_insn "neon_vdup_ndi"
2714 [(set (match_operand:DI 0 "s_register_operand" "=w")
2715 (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")]
2718 "vmov%?\t%P0, %Q1, %R1"
2719 [(set_attr "predicable" "yes")
2720 (set_attr "neon_type" "neon_bp_simple")]
2723 (define_insn "neon_vdup_nv2di"
2724 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2725 (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "r")]
2728 "vmov%?\t%e0, %Q1, %R1\;vmov%?\t%f0, %Q1, %R1"
2729 [(set_attr "predicable" "yes")
2730 (set_attr "length" "8")
2731 (set_attr "neon_type" "neon_bp_simple")]
2734 (define_insn "neon_vdup_lane<mode>"
2735 [(set (match_operand:VD 0 "s_register_operand" "=w")
2736 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2737 (match_operand:SI 2 "immediate_operand" "i")]
2741 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode));
2742 return "vdup.<V_sz_elem>\t%P0, %P1[%c2]";
2744 ;; Assume this schedules like vmov.
2745 [(set_attr "neon_type" "neon_bp_simple")]
2748 (define_insn "neon_vdup_lane<mode>"
2749 [(set (match_operand:VQ 0 "s_register_operand" "=w")
2750 (unspec:VQ [(match_operand:<V_HALF> 1 "s_register_operand" "w")
2751 (match_operand:SI 2 "immediate_operand" "i")]
2755 neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<V_HALF>mode));
2756 return "vdup.<V_sz_elem>\t%q0, %P1[%c2]";
2758 ;; Assume this schedules like vmov.
2759 [(set_attr "neon_type" "neon_bp_simple")]
2762 ; Scalar index is ignored, since only zero is valid here.
2763 (define_expand "neon_vdup_lanedi"
2764 [(set (match_operand:DI 0 "s_register_operand" "=w")
2765 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
2766 (match_operand:SI 2 "immediate_operand" "i")]
2770 neon_lane_bounds (operands[2], 0, 1);
2771 emit_move_insn (operands[0], operands[1]);
2776 (define_insn "neon_vdup_lanev2di"
2777 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2778 (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "w")
2779 (match_operand:SI 2 "immediate_operand" "i")]
2783 neon_lane_bounds (operands[2], 0, 1);
2784 return "vmov\t%e0, %P1\;vmov\t%f0, %P1";
2786 [(set_attr "length" "8")
2787 (set_attr "neon_type" "neon_bp_simple")]
2790 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
2792 ;; FIXME: A different implementation of this builtin could make it much
2793 ;; more likely that we wouldn't actually need to output anything (we could make
2794 ;; it so that the reg allocator puts things in the right places magically
2795 ;; instead). Lack of subregs for vectors makes that tricky though, I think.
2797 (define_insn "neon_vcombine<mode>"
2798 [(set (match_operand:<V_DOUBLE> 0 "s_register_operand" "=w")
2799 (unspec:<V_DOUBLE> [(match_operand:VDX 1 "s_register_operand" "w")
2800 (match_operand:VDX 2 "s_register_operand" "w")]
2804 int dest = REGNO (operands[0]);
2805 int src1 = REGNO (operands[1]);
2806 int src2 = REGNO (operands[2]);
2809 if (src1 == dest && src2 == dest + 2)
2811 else if (src2 == dest && src1 == dest + 2)
2812 /* Special case of reversed high/low parts. */
2813 return "vswp\t%P1, %P2";
2815 destlo = gen_rtx_REG (<MODE>mode, dest);
2817 if (!reg_overlap_mentioned_p (operands[2], destlo))
2819 /* Try to avoid unnecessary moves if part of the result is in the right
2822 output_asm_insn ("vmov\t%e0, %P1", operands);
2823 if (src2 != dest + 2)
2824 output_asm_insn ("vmov\t%f0, %P2", operands);
2828 if (src2 != dest + 2)
2829 output_asm_insn ("vmov\t%f0, %P2", operands);
2831 output_asm_insn ("vmov\t%e0, %P1", operands);
2836 ;; We set the neon_type attribute based on the vmov instructions above.
2837 [(set_attr "length" "8")
2838 (set_attr "neon_type" "neon_bp_simple")]
2841 (define_insn "neon_vget_high<mode>"
2842 [(set (match_operand:<V_HALF> 0 "s_register_operand" "=w")
2843 (unspec:<V_HALF> [(match_operand:VQX 1 "s_register_operand" "w")]
2847 int dest = REGNO (operands[0]);
2848 int src = REGNO (operands[1]);
2850 if (dest != src + 2)
2851 return "vmov\t%P0, %f1";
2855 [(set_attr "neon_type" "neon_bp_simple")]
2858 (define_insn "neon_vget_low<mode>"
2859 [(set (match_operand:<V_HALF> 0 "s_register_operand" "=w")
2860 (unspec:<V_HALF> [(match_operand:VQX 1 "s_register_operand" "w")]
2864 int dest = REGNO (operands[0]);
2865 int src = REGNO (operands[1]);
2868 return "vmov\t%P0, %e1";
2872 [(set_attr "neon_type" "neon_bp_simple")]
2875 (define_insn "neon_vcvt<mode>"
2876 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2877 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
2878 (match_operand:SI 2 "immediate_operand" "i")]
2881 "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1"
2882 [(set (attr "neon_type")
2883 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2884 (const_string "neon_fp_vadd_ddd_vabs_dd")
2885 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2888 (define_insn "neon_vcvt<mode>"
2889 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2890 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
2891 (match_operand:SI 2 "immediate_operand" "i")]
2894 "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1"
2895 [(set (attr "neon_type")
2896 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2897 (const_string "neon_fp_vadd_ddd_vabs_dd")
2898 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2901 (define_insn "neon_vcvt_n<mode>"
2902 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2903 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
2904 (match_operand:SI 2 "immediate_operand" "i")
2905 (match_operand:SI 3 "immediate_operand" "i")]
2909 neon_const_bounds (operands[2], 1, 33);
2910 return "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2";
2912 [(set (attr "neon_type")
2913 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2914 (const_string "neon_fp_vadd_ddd_vabs_dd")
2915 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2918 (define_insn "neon_vcvt_n<mode>"
2919 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2920 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
2921 (match_operand:SI 2 "immediate_operand" "i")
2922 (match_operand:SI 3 "immediate_operand" "i")]
2926 neon_const_bounds (operands[2], 1, 33);
2927 return "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2";
2929 [(set (attr "neon_type")
2930 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2931 (const_string "neon_fp_vadd_ddd_vabs_dd")
2932 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2935 (define_insn "neon_vmovn<mode>"
2936 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2937 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2938 (match_operand:SI 2 "immediate_operand" "i")]
2941 "vmovn.<V_if_elem>\t%P0, %q1"
2942 [(set_attr "neon_type" "neon_bp_simple")]
2945 (define_insn "neon_vqmovn<mode>"
2946 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2947 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2948 (match_operand:SI 2 "immediate_operand" "i")]
2951 "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1"
2952 [(set_attr "neon_type" "neon_shift_2")]
2955 (define_insn "neon_vqmovun<mode>"
2956 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2957 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2958 (match_operand:SI 2 "immediate_operand" "i")]
2961 "vqmovun.<V_s_elem>\t%P0, %q1"
2962 [(set_attr "neon_type" "neon_shift_2")]
2965 (define_insn "neon_vmovl<mode>"
2966 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2967 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2968 (match_operand:SI 2 "immediate_operand" "i")]
2971 "vmovl.%T2%#<V_sz_elem>\t%q0, %P1"
2972 [(set_attr "neon_type" "neon_shift_1")]
2975 (define_insn "neon_vmul_lane<mode>"
2976 [(set (match_operand:VMD 0 "s_register_operand" "=w")
2977 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
2978 (match_operand:VMD 2 "s_register_operand"
2979 "<scalar_mul_constraint>")
2980 (match_operand:SI 3 "immediate_operand" "i")
2981 (match_operand:SI 4 "immediate_operand" "i")]
2985 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
2986 return "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]";
2988 [(set (attr "neon_type")
2989 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2990 (const_string "neon_fp_vmul_ddd")
2991 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2992 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
2993 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))))]
2996 (define_insn "neon_vmul_lane<mode>"
2997 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
2998 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
2999 (match_operand:<V_HALF> 2 "s_register_operand"
3000 "<scalar_mul_constraint>")
3001 (match_operand:SI 3 "immediate_operand" "i")
3002 (match_operand:SI 4 "immediate_operand" "i")]
3006 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<V_HALF>mode));
3007 return "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]";
3009 [(set (attr "neon_type")
3010 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3011 (const_string "neon_fp_vmul_qqd")
3012 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3013 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3014 (const_string "neon_mul_qqd_32_scalar"))))]
3017 (define_insn "neon_vmull_lane<mode>"
3018 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3019 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3020 (match_operand:VMDI 2 "s_register_operand"
3021 "<scalar_mul_constraint>")
3022 (match_operand:SI 3 "immediate_operand" "i")
3023 (match_operand:SI 4 "immediate_operand" "i")]
3024 UNSPEC_VMULL_LANE))]
3027 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3028 return "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]";
3030 [(set (attr "neon_type")
3031 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3032 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3033 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3036 (define_insn "neon_vqdmull_lane<mode>"
3037 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3038 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3039 (match_operand:VMDI 2 "s_register_operand"
3040 "<scalar_mul_constraint>")
3041 (match_operand:SI 3 "immediate_operand" "i")
3042 (match_operand:SI 4 "immediate_operand" "i")]
3043 UNSPEC_VQDMULL_LANE))]
3046 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3047 return "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]";
3049 [(set (attr "neon_type")
3050 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3051 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3052 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3055 (define_insn "neon_vqdmulh_lane<mode>"
3056 [(set (match_operand:VMQI 0 "s_register_operand" "=w")
3057 (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
3058 (match_operand:<V_HALF> 2 "s_register_operand"
3059 "<scalar_mul_constraint>")
3060 (match_operand:SI 3 "immediate_operand" "i")
3061 (match_operand:SI 4 "immediate_operand" "i")]
3062 UNSPEC_VQDMULH_LANE))]
3065 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3066 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]";
3068 [(set (attr "neon_type")
3069 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3070 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3071 (const_string "neon_mul_qqd_32_scalar")))]
3074 (define_insn "neon_vqdmulh_lane<mode>"
3075 [(set (match_operand:VMDI 0 "s_register_operand" "=w")
3076 (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
3077 (match_operand:VMDI 2 "s_register_operand"
3078 "<scalar_mul_constraint>")
3079 (match_operand:SI 3 "immediate_operand" "i")
3080 (match_operand:SI 4 "immediate_operand" "i")]
3081 UNSPEC_VQDMULH_LANE))]
3084 neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3085 return "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]";
3087 [(set (attr "neon_type")
3088 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3089 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3090 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3093 (define_insn "neon_vmla_lane<mode>"
3094 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3095 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3096 (match_operand:VMD 2 "s_register_operand" "w")
3097 (match_operand:VMD 3 "s_register_operand"
3098 "<scalar_mul_constraint>")
3099 (match_operand:SI 4 "immediate_operand" "i")
3100 (match_operand:SI 5 "immediate_operand" "i")]
3104 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3105 return "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3107 [(set (attr "neon_type")
3108 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3109 (const_string "neon_fp_vmla_ddd_scalar")
3110 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3111 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3112 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3115 (define_insn "neon_vmla_lane<mode>"
3116 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3117 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3118 (match_operand:VMQ 2 "s_register_operand" "w")
3119 (match_operand:<V_HALF> 3 "s_register_operand"
3120 "<scalar_mul_constraint>")
3121 (match_operand:SI 4 "immediate_operand" "i")
3122 (match_operand:SI 5 "immediate_operand" "i")]
3126 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3127 return "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3129 [(set (attr "neon_type")
3130 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3131 (const_string "neon_fp_vmla_qqq_scalar")
3132 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3133 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3134 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3137 (define_insn "neon_vmlal_lane<mode>"
3138 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3139 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3140 (match_operand:VMDI 2 "s_register_operand" "w")
3141 (match_operand:VMDI 3 "s_register_operand"
3142 "<scalar_mul_constraint>")
3143 (match_operand:SI 4 "immediate_operand" "i")
3144 (match_operand:SI 5 "immediate_operand" "i")]
3145 UNSPEC_VMLAL_LANE))]
3148 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3149 return "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3151 [(set (attr "neon_type")
3152 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3153 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3154 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3157 (define_insn "neon_vqdmlal_lane<mode>"
3158 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3159 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3160 (match_operand:VMDI 2 "s_register_operand" "w")
3161 (match_operand:VMDI 3 "s_register_operand"
3162 "<scalar_mul_constraint>")
3163 (match_operand:SI 4 "immediate_operand" "i")
3164 (match_operand:SI 5 "immediate_operand" "i")]
3165 UNSPEC_VQDMLAL_LANE))]
3168 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3169 return "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3171 [(set (attr "neon_type")
3172 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3173 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3174 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3177 (define_insn "neon_vmls_lane<mode>"
3178 [(set (match_operand:VMD 0 "s_register_operand" "=w")
3179 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3180 (match_operand:VMD 2 "s_register_operand" "w")
3181 (match_operand:VMD 3 "s_register_operand"
3182 "<scalar_mul_constraint>")
3183 (match_operand:SI 4 "immediate_operand" "i")
3184 (match_operand:SI 5 "immediate_operand" "i")]
3188 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3189 return "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3191 [(set (attr "neon_type")
3192 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3193 (const_string "neon_fp_vmla_ddd_scalar")
3194 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3195 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3196 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3199 (define_insn "neon_vmls_lane<mode>"
3200 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3201 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3202 (match_operand:VMQ 2 "s_register_operand" "w")
3203 (match_operand:<V_HALF> 3 "s_register_operand"
3204 "<scalar_mul_constraint>")
3205 (match_operand:SI 4 "immediate_operand" "i")
3206 (match_operand:SI 5 "immediate_operand" "i")]
3210 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3211 return "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3213 [(set (attr "neon_type")
3214 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3215 (const_string "neon_fp_vmla_qqq_scalar")
3216 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3217 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3218 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3221 (define_insn "neon_vmlsl_lane<mode>"
3222 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3223 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3224 (match_operand:VMDI 2 "s_register_operand" "w")
3225 (match_operand:VMDI 3 "s_register_operand"
3226 "<scalar_mul_constraint>")
3227 (match_operand:SI 4 "immediate_operand" "i")
3228 (match_operand:SI 5 "immediate_operand" "i")]
3229 UNSPEC_VMLSL_LANE))]
3232 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3233 return "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3235 [(set (attr "neon_type")
3236 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3237 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3238 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3241 (define_insn "neon_vqdmlsl_lane<mode>"
3242 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3243 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3244 (match_operand:VMDI 2 "s_register_operand" "w")
3245 (match_operand:VMDI 3 "s_register_operand"
3246 "<scalar_mul_constraint>")
3247 (match_operand:SI 4 "immediate_operand" "i")
3248 (match_operand:SI 5 "immediate_operand" "i")]
3249 UNSPEC_VQDMLSL_LANE))]
3252 neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3253 return "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3255 [(set (attr "neon_type")
3256 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3257 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3258 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3261 ; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
3262 ; core register into a temp register, then use a scalar taken from that. This
3263 ; isn't an optimal solution if e.g. the scalar has just been read from memory
3264 ; or extracted from another vector. The latter case it's currently better to
3265 ; use the "_lane" variant, and the former case can probably be implemented
3266 ; using vld1_lane, but that hasn't been done yet.
3268 (define_expand "neon_vmul_n<mode>"
3269 [(match_operand:VMD 0 "s_register_operand" "")
3270 (match_operand:VMD 1 "s_register_operand" "")
3271 (match_operand:<V_elem> 2 "s_register_operand" "")
3272 (match_operand:SI 3 "immediate_operand" "")]
3275 rtx tmp = gen_reg_rtx (<MODE>mode);
3276 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3277 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3278 const0_rtx, const0_rtx));
3282 (define_expand "neon_vmul_n<mode>"
3283 [(match_operand:VMQ 0 "s_register_operand" "")
3284 (match_operand:VMQ 1 "s_register_operand" "")
3285 (match_operand:<V_elem> 2 "s_register_operand" "")
3286 (match_operand:SI 3 "immediate_operand" "")]
3289 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3290 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3291 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3292 const0_rtx, const0_rtx));
3296 (define_expand "neon_vmull_n<mode>"
3297 [(match_operand:<V_widen> 0 "s_register_operand" "")
3298 (match_operand:VMDI 1 "s_register_operand" "")
3299 (match_operand:<V_elem> 2 "s_register_operand" "")
3300 (match_operand:SI 3 "immediate_operand" "")]
3303 rtx tmp = gen_reg_rtx (<MODE>mode);
3304 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3305 emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp,
3306 const0_rtx, operands[3]));
3310 (define_expand "neon_vqdmull_n<mode>"
3311 [(match_operand:<V_widen> 0 "s_register_operand" "")
3312 (match_operand:VMDI 1 "s_register_operand" "")
3313 (match_operand:<V_elem> 2 "s_register_operand" "")
3314 (match_operand:SI 3 "immediate_operand" "")]
3317 rtx tmp = gen_reg_rtx (<MODE>mode);
3318 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3319 emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp,
3320 const0_rtx, const0_rtx));
3324 (define_expand "neon_vqdmulh_n<mode>"
3325 [(match_operand:VMDI 0 "s_register_operand" "")
3326 (match_operand:VMDI 1 "s_register_operand" "")
3327 (match_operand:<V_elem> 2 "s_register_operand" "")
3328 (match_operand:SI 3 "immediate_operand" "")]
3331 rtx tmp = gen_reg_rtx (<MODE>mode);
3332 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3333 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3334 const0_rtx, operands[3]));
3338 (define_expand "neon_vqdmulh_n<mode>"
3339 [(match_operand:VMQI 0 "s_register_operand" "")
3340 (match_operand:VMQI 1 "s_register_operand" "")
3341 (match_operand:<V_elem> 2 "s_register_operand" "")
3342 (match_operand:SI 3 "immediate_operand" "")]
3345 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3346 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3347 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3348 const0_rtx, operands[3]));
3352 (define_expand "neon_vmla_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_vmla_lane<mode> (operands[0], operands[1], operands[2],
3363 tmp, const0_rtx, operands[4]));
3367 (define_expand "neon_vmla_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_vmla_lane<mode> (operands[0], operands[1], operands[2],
3378 tmp, const0_rtx, operands[4]));
3382 (define_expand "neon_vmlal_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_vmlal_lane<mode> (operands[0], operands[1], operands[2],
3393 tmp, const0_rtx, operands[4]));
3397 (define_expand "neon_vqdmlal_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_vqdmlal_lane<mode> (operands[0], operands[1], operands[2],
3408 tmp, const0_rtx, operands[4]));
3412 (define_expand "neon_vmls_n<mode>"
3413 [(match_operand:VMD 0 "s_register_operand" "")
3414 (match_operand:VMD 1 "s_register_operand" "")
3415 (match_operand:VMD 2 "s_register_operand" "")
3416 (match_operand:<V_elem> 3 "s_register_operand" "")
3417 (match_operand:SI 4 "immediate_operand" "")]
3420 rtx tmp = gen_reg_rtx (<MODE>mode);
3421 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3422 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3423 tmp, const0_rtx, operands[4]));
3427 (define_expand "neon_vmls_n<mode>"
3428 [(match_operand:VMQ 0 "s_register_operand" "")
3429 (match_operand:VMQ 1 "s_register_operand" "")
3430 (match_operand:VMQ 2 "s_register_operand" "")
3431 (match_operand:<V_elem> 3 "s_register_operand" "")
3432 (match_operand:SI 4 "immediate_operand" "")]
3435 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3436 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3437 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3438 tmp, const0_rtx, operands[4]));
3442 (define_expand "neon_vmlsl_n<mode>"
3443 [(match_operand:<V_widen> 0 "s_register_operand" "")
3444 (match_operand:<V_widen> 1 "s_register_operand" "")
3445 (match_operand:VMDI 2 "s_register_operand" "")
3446 (match_operand:<V_elem> 3 "s_register_operand" "")
3447 (match_operand:SI 4 "immediate_operand" "")]
3450 rtx tmp = gen_reg_rtx (<MODE>mode);
3451 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3452 emit_insn (gen_neon_vmlsl_lane<mode> (operands[0], operands[1], operands[2],
3453 tmp, const0_rtx, operands[4]));
3457 (define_expand "neon_vqdmlsl_n<mode>"
3458 [(match_operand:<V_widen> 0 "s_register_operand" "")
3459 (match_operand:<V_widen> 1 "s_register_operand" "")
3460 (match_operand:VMDI 2 "s_register_operand" "")
3461 (match_operand:<V_elem> 3 "s_register_operand" "")
3462 (match_operand:SI 4 "immediate_operand" "")]
3465 rtx tmp = gen_reg_rtx (<MODE>mode);
3466 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3467 emit_insn (gen_neon_vqdmlsl_lane<mode> (operands[0], operands[1], operands[2],
3468 tmp, const0_rtx, operands[4]));
3472 (define_insn "neon_vext<mode>"
3473 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
3474 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
3475 (match_operand:VDQX 2 "s_register_operand" "w")
3476 (match_operand:SI 3 "immediate_operand" "i")]
3480 neon_const_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3481 return "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3";
3483 [(set (attr "neon_type")
3484 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3485 (const_string "neon_bp_simple")
3486 (const_string "neon_bp_2cycle")))]
3489 (define_insn "neon_vrev64<mode>"
3490 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
3491 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
3492 (match_operand:SI 2 "immediate_operand" "i")]
3495 "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3496 [(set_attr "neon_type" "neon_bp_simple")]
3499 (define_insn "neon_vrev32<mode>"
3500 [(set (match_operand:VX 0 "s_register_operand" "=w")
3501 (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")
3502 (match_operand:SI 2 "immediate_operand" "i")]
3505 "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3506 [(set_attr "neon_type" "neon_bp_simple")]
3509 (define_insn "neon_vrev16<mode>"
3510 [(set (match_operand:VE 0 "s_register_operand" "=w")
3511 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
3512 (match_operand:SI 2 "immediate_operand" "i")]
3515 "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3516 [(set_attr "neon_type" "neon_bp_simple")]
3519 ; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
3520 ; allocation. For an intrinsic of form:
3521 ; rD = vbsl_* (rS, rN, rM)
3522 ; We can use any of:
3523 ; vbsl rS, rN, rM (if D = S)
3524 ; vbit rD, rN, rS (if D = M, so 1-bits in rS choose bits from rN, else rM)
3525 ; vbif rD, rM, rS (if D = N, so 0-bits in rS choose bits from rM, else rN)
3527 (define_insn "neon_vbsl<mode>_internal"
3528 [(set (match_operand:VDQX 0 "s_register_operand" "=w,w,w")
3529 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" " 0,w,w")
3530 (match_operand:VDQX 2 "s_register_operand" " w,w,0")
3531 (match_operand:VDQX 3 "s_register_operand" " w,0,w")]
3535 vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3
3536 vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1
3537 vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1"
3538 [(set_attr "neon_type" "neon_int_1")]
3541 (define_expand "neon_vbsl<mode>"
3542 [(set (match_operand:VDQX 0 "s_register_operand" "")
3543 (unspec:VDQX [(match_operand:<V_cmp_result> 1 "s_register_operand" "")
3544 (match_operand:VDQX 2 "s_register_operand" "")
3545 (match_operand:VDQX 3 "s_register_operand" "")]
3549 /* We can't alias operands together if they have different modes. */
3550 operands[1] = gen_lowpart (<MODE>mode, operands[1]);
3553 (define_insn "neon_vshl<mode>"
3554 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3555 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3556 (match_operand:VDQIX 2 "s_register_operand" "w")
3557 (match_operand:SI 3 "immediate_operand" "i")]
3560 "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3561 [(set (attr "neon_type")
3562 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3563 (const_string "neon_vshl_ddd")
3564 (const_string "neon_shift_3")))]
3567 (define_insn "neon_vqshl<mode>"
3568 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3569 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3570 (match_operand:VDQIX 2 "s_register_operand" "w")
3571 (match_operand:SI 3 "immediate_operand" "i")]
3574 "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3575 [(set (attr "neon_type")
3576 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3577 (const_string "neon_shift_2")
3578 (const_string "neon_vqshl_vrshl_vqrshl_qqq")))]
3581 (define_insn "neon_vshr_n<mode>"
3582 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3583 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3584 (match_operand:SI 2 "immediate_operand" "i")
3585 (match_operand:SI 3 "immediate_operand" "i")]
3589 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) + 1);
3590 return "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3592 [(set_attr "neon_type" "neon_shift_1")]
3595 (define_insn "neon_vshrn_n<mode>"
3596 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3597 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3598 (match_operand:SI 2 "immediate_operand" "i")
3599 (match_operand:SI 3 "immediate_operand" "i")]
3603 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3604 return "v%O3shrn.<V_if_elem>\t%P0, %q1, %2";
3606 [(set_attr "neon_type" "neon_shift_1")]
3609 (define_insn "neon_vqshrn_n<mode>"
3610 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3611 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3612 (match_operand:SI 2 "immediate_operand" "i")
3613 (match_operand:SI 3 "immediate_operand" "i")]
3617 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3618 return "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3620 [(set_attr "neon_type" "neon_shift_2")]
3623 (define_insn "neon_vqshrun_n<mode>"
3624 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3625 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3626 (match_operand:SI 2 "immediate_operand" "i")
3627 (match_operand:SI 3 "immediate_operand" "i")]
3631 neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3632 return "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2";
3634 [(set_attr "neon_type" "neon_shift_2")]
3637 (define_insn "neon_vshl_n<mode>"
3638 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3639 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3640 (match_operand:SI 2 "immediate_operand" "i")
3641 (match_operand:SI 3 "immediate_operand" "i")]
3645 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3646 return "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2";
3648 [(set_attr "neon_type" "neon_shift_1")]
3651 (define_insn "neon_vqshl_n<mode>"
3652 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3653 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3654 (match_operand:SI 2 "immediate_operand" "i")
3655 (match_operand:SI 3 "immediate_operand" "i")]
3659 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3660 return "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3662 [(set_attr "neon_type" "neon_shift_2")]
3665 (define_insn "neon_vqshlu_n<mode>"
3666 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3667 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3668 (match_operand:SI 2 "immediate_operand" "i")
3669 (match_operand:SI 3 "immediate_operand" "i")]
3673 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
3674 return "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3676 [(set_attr "neon_type" "neon_shift_2")]
3679 (define_insn "neon_vshll_n<mode>"
3680 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3681 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
3682 (match_operand:SI 2 "immediate_operand" "i")
3683 (match_operand:SI 3 "immediate_operand" "i")]
3687 /* The boundaries are: 0 < imm <= size. */
3688 neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode) + 1);
3689 return "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2";
3691 [(set_attr "neon_type" "neon_shift_1")]
3694 (define_insn "neon_vsra_n<mode>"
3695 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3696 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3697 (match_operand:VDQIX 2 "s_register_operand" "w")
3698 (match_operand:SI 3 "immediate_operand" "i")
3699 (match_operand:SI 4 "immediate_operand" "i")]
3703 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
3704 return "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3706 [(set_attr "neon_type" "neon_vsra_vrsra")]
3709 (define_insn "neon_vsri_n<mode>"
3710 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3711 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3712 (match_operand:VDQIX 2 "s_register_operand" "w")
3713 (match_operand:SI 3 "immediate_operand" "i")]
3717 neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
3718 return "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3720 [(set (attr "neon_type")
3721 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3722 (const_string "neon_shift_1")
3723 (const_string "neon_shift_3")))]
3726 (define_insn "neon_vsli_n<mode>"
3727 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3728 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3729 (match_operand:VDQIX 2 "s_register_operand" "w")
3730 (match_operand:SI 3 "immediate_operand" "i")]
3734 neon_const_bounds (operands[3], 0, neon_element_bits (<MODE>mode));
3735 return "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
3737 [(set (attr "neon_type")
3738 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3739 (const_string "neon_shift_1")
3740 (const_string "neon_shift_3")))]
3743 (define_insn "neon_vtbl1v8qi"
3744 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3745 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")
3746 (match_operand:V8QI 2 "s_register_operand" "w")]
3749 "vtbl.8\t%P0, {%P1}, %P2"
3750 [(set_attr "neon_type" "neon_bp_2cycle")]
3753 (define_insn "neon_vtbl2v8qi"
3754 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3755 (unspec:V8QI [(match_operand:TI 1 "s_register_operand" "w")
3756 (match_operand:V8QI 2 "s_register_operand" "w")]
3761 int tabbase = REGNO (operands[1]);
3763 ops[0] = operands[0];
3764 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3765 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3766 ops[3] = operands[2];
3767 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2}, %P3", ops);
3771 [(set_attr "neon_type" "neon_bp_2cycle")]
3774 (define_insn "neon_vtbl3v8qi"
3775 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3776 (unspec:V8QI [(match_operand:EI 1 "s_register_operand" "w")
3777 (match_operand:V8QI 2 "s_register_operand" "w")]
3782 int tabbase = REGNO (operands[1]);
3784 ops[0] = operands[0];
3785 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3786 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3787 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3788 ops[4] = operands[2];
3789 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
3793 [(set_attr "neon_type" "neon_bp_3cycle")]
3796 (define_insn "neon_vtbl4v8qi"
3797 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3798 (unspec:V8QI [(match_operand:OI 1 "s_register_operand" "w")
3799 (match_operand:V8QI 2 "s_register_operand" "w")]
3804 int tabbase = REGNO (operands[1]);
3806 ops[0] = operands[0];
3807 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3808 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3809 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3810 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
3811 ops[5] = operands[2];
3812 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
3816 [(set_attr "neon_type" "neon_bp_3cycle")]
3819 (define_insn "neon_vtbx1v8qi"
3820 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3821 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3822 (match_operand:V8QI 2 "s_register_operand" "w")
3823 (match_operand:V8QI 3 "s_register_operand" "w")]
3826 "vtbx.8\t%P0, {%P2}, %P3"
3827 [(set_attr "neon_type" "neon_bp_2cycle")]
3830 (define_insn "neon_vtbx2v8qi"
3831 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3832 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3833 (match_operand:TI 2 "s_register_operand" "w")
3834 (match_operand:V8QI 3 "s_register_operand" "w")]
3839 int tabbase = REGNO (operands[2]);
3841 ops[0] = operands[0];
3842 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3843 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3844 ops[3] = operands[3];
3845 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2}, %P3", ops);
3849 [(set_attr "neon_type" "neon_bp_2cycle")]
3852 (define_insn "neon_vtbx3v8qi"
3853 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3854 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3855 (match_operand:EI 2 "s_register_operand" "w")
3856 (match_operand:V8QI 3 "s_register_operand" "w")]
3861 int tabbase = REGNO (operands[2]);
3863 ops[0] = operands[0];
3864 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3865 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3866 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3867 ops[4] = operands[3];
3868 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
3872 [(set_attr "neon_type" "neon_bp_3cycle")]
3875 (define_insn "neon_vtbx4v8qi"
3876 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3877 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3878 (match_operand:OI 2 "s_register_operand" "w")
3879 (match_operand:V8QI 3 "s_register_operand" "w")]
3884 int tabbase = REGNO (operands[2]);
3886 ops[0] = operands[0];
3887 ops[1] = gen_rtx_REG (V8QImode, tabbase);
3888 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3889 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3890 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
3891 ops[5] = operands[3];
3892 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
3896 [(set_attr "neon_type" "neon_bp_3cycle")]
3899 (define_insn "neon_vtrn<mode>_internal"
3900 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3901 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
3903 (set (match_operand:VDQW 2 "s_register_operand" "=w")
3904 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
3907 "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
3908 [(set (attr "neon_type")
3909 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3910 (const_string "neon_bp_simple")
3911 (const_string "neon_bp_3cycle")))]
3914 (define_expand "neon_vtrn<mode>"
3915 [(match_operand:SI 0 "s_register_operand" "r")
3916 (match_operand:VDQW 1 "s_register_operand" "w")
3917 (match_operand:VDQW 2 "s_register_operand" "w")]
3920 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vtrn<mode>_internal,
3921 operands[0], operands[1], operands[2]);
3925 (define_insn "neon_vzip<mode>_internal"
3926 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3927 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
3929 (set (match_operand:VDQW 2 "s_register_operand" "=w")
3930 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
3933 "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
3934 [(set (attr "neon_type")
3935 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3936 (const_string "neon_bp_simple")
3937 (const_string "neon_bp_3cycle")))]
3940 (define_expand "neon_vzip<mode>"
3941 [(match_operand:SI 0 "s_register_operand" "r")
3942 (match_operand:VDQW 1 "s_register_operand" "w")
3943 (match_operand:VDQW 2 "s_register_operand" "w")]
3946 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vzip<mode>_internal,
3947 operands[0], operands[1], operands[2]);
3951 (define_insn "neon_vuzp<mode>_internal"
3952 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3953 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
3955 (set (match_operand:VDQW 2 "s_register_operand" "=w")
3956 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
3959 "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
3960 [(set (attr "neon_type")
3961 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
3962 (const_string "neon_bp_simple")
3963 (const_string "neon_bp_3cycle")))]
3966 (define_expand "neon_vuzp<mode>"
3967 [(match_operand:SI 0 "s_register_operand" "r")
3968 (match_operand:VDQW 1 "s_register_operand" "w")
3969 (match_operand:VDQW 2 "s_register_operand" "w")]
3972 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vuzp<mode>_internal,
3973 operands[0], operands[1], operands[2]);
3977 (define_expand "neon_vreinterpretv8qi<mode>"
3978 [(match_operand:V8QI 0 "s_register_operand" "")
3979 (match_operand:VDX 1 "s_register_operand" "")]
3982 neon_reinterpret (operands[0], operands[1]);
3986 (define_expand "neon_vreinterpretv4hi<mode>"
3987 [(match_operand:V4HI 0 "s_register_operand" "")
3988 (match_operand:VDX 1 "s_register_operand" "")]
3991 neon_reinterpret (operands[0], operands[1]);
3995 (define_expand "neon_vreinterpretv2si<mode>"
3996 [(match_operand:V2SI 0 "s_register_operand" "")
3997 (match_operand:VDX 1 "s_register_operand" "")]
4000 neon_reinterpret (operands[0], operands[1]);
4004 (define_expand "neon_vreinterpretv2sf<mode>"
4005 [(match_operand:V2SF 0 "s_register_operand" "")
4006 (match_operand:VDX 1 "s_register_operand" "")]
4009 neon_reinterpret (operands[0], operands[1]);
4013 (define_expand "neon_vreinterpretdi<mode>"
4014 [(match_operand:DI 0 "s_register_operand" "")
4015 (match_operand:VDX 1 "s_register_operand" "")]
4018 neon_reinterpret (operands[0], operands[1]);
4022 (define_expand "neon_vreinterpretv16qi<mode>"
4023 [(match_operand:V16QI 0 "s_register_operand" "")
4024 (match_operand:VQX 1 "s_register_operand" "")]
4027 neon_reinterpret (operands[0], operands[1]);
4031 (define_expand "neon_vreinterpretv8hi<mode>"
4032 [(match_operand:V8HI 0 "s_register_operand" "")
4033 (match_operand:VQX 1 "s_register_operand" "")]
4036 neon_reinterpret (operands[0], operands[1]);
4040 (define_expand "neon_vreinterpretv4si<mode>"
4041 [(match_operand:V4SI 0 "s_register_operand" "")
4042 (match_operand:VQX 1 "s_register_operand" "")]
4045 neon_reinterpret (operands[0], operands[1]);
4049 (define_expand "neon_vreinterpretv4sf<mode>"
4050 [(match_operand:V4SF 0 "s_register_operand" "")
4051 (match_operand:VQX 1 "s_register_operand" "")]
4054 neon_reinterpret (operands[0], operands[1]);
4058 (define_expand "neon_vreinterpretv2di<mode>"
4059 [(match_operand:V2DI 0 "s_register_operand" "")
4060 (match_operand:VQX 1 "s_register_operand" "")]
4063 neon_reinterpret (operands[0], operands[1]);
4067 (define_insn "neon_vld1<mode>"
4068 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
4069 (unspec:VDQX [(mem:VDQX (match_operand:SI 1 "s_register_operand" "r"))]
4072 "vld1.<V_sz_elem>\t%h0, [%1]"
4073 [(set_attr "neon_type" "neon_vld1_1_2_regs")]
4076 (define_insn "neon_vld1_lane<mode>"
4077 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4078 (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
4079 (match_operand:VDX 2 "s_register_operand" "0")
4080 (match_operand:SI 3 "immediate_operand" "i")]
4084 HOST_WIDE_INT lane = INTVAL (operands[3]);
4085 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4086 if (lane < 0 || lane >= max)
4087 error ("lane out of range");
4089 return "vld1.<V_sz_elem>\t%P0, [%1]";
4091 return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
4093 [(set (attr "neon_type")
4094 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4095 (const_string "neon_vld1_1_2_regs")
4096 (const_string "neon_vld1_vld2_lane")))]
4099 (define_insn "neon_vld1_lane<mode>"
4100 [(set (match_operand:VQX 0 "s_register_operand" "=w")
4101 (unspec:VQX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
4102 (match_operand:VQX 2 "s_register_operand" "0")
4103 (match_operand:SI 3 "immediate_operand" "i")]
4107 HOST_WIDE_INT lane = INTVAL (operands[3]);
4108 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4109 int regno = REGNO (operands[0]);
4110 if (lane < 0 || lane >= max)
4111 error ("lane out of range");
4112 else if (lane >= max / 2)
4116 operands[3] = GEN_INT (lane);
4118 operands[0] = gen_rtx_REG (<V_HALF>mode, regno);
4120 return "vld1.<V_sz_elem>\t%P0, [%1]";
4122 return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
4124 [(set (attr "neon_type")
4125 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4126 (const_string "neon_vld1_1_2_regs")
4127 (const_string "neon_vld1_vld2_lane")))]
4130 (define_insn "neon_vld1_dup<mode>"
4131 [(set (match_operand:VDX 0 "s_register_operand" "=w")
4132 (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))]
4136 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4137 return "vld1.<V_sz_elem>\t{%P0[]}, [%1]";
4139 return "vld1.<V_sz_elem>\t%h0, [%1]";
4141 [(set (attr "neon_type")
4142 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4143 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4144 (const_string "neon_vld1_1_2_regs")))]
4147 (define_insn "neon_vld1_dup<mode>"
4148 [(set (match_operand:VQX 0 "s_register_operand" "=w")
4149 (unspec:VQX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))]
4153 if (GET_MODE_NUNITS (<MODE>mode) > 2)
4154 return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
4156 return "vld1.<V_sz_elem>\t%h0, [%1]";
4158 [(set (attr "neon_type")
4159 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4160 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4161 (const_string "neon_vld1_1_2_regs")))]
4164 (define_insn "neon_vst1<mode>"
4165 [(set (mem:VDQX (match_operand:SI 0 "s_register_operand" "r"))
4166 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")]
4169 "vst1.<V_sz_elem>\t%h1, [%0]"
4170 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
4172 (define_insn "neon_vst1_lane<mode>"
4173 [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
4174 (vec_select:<V_elem>
4175 (match_operand:VDX 1 "s_register_operand" "w")
4176 (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
4179 HOST_WIDE_INT lane = INTVAL (operands[2]);
4180 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4181 if (lane < 0 || lane >= max)
4182 error ("lane out of range");
4184 return "vst1.<V_sz_elem>\t{%P1}, [%0]";
4186 return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
4188 [(set (attr "neon_type")
4189 (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 1))
4190 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4191 (const_string "neon_vst1_vst2_lane")))])
4193 (define_insn "neon_vst1_lane<mode>"
4194 [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
4195 (vec_select:<V_elem>
4196 (match_operand:VQX 1 "s_register_operand" "w")
4197 (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
4200 HOST_WIDE_INT lane = INTVAL (operands[2]);
4201 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4202 int regno = REGNO (operands[1]);
4203 if (lane < 0 || lane >= max)
4204 error ("lane out of range");
4205 else if (lane >= max / 2)
4209 operands[2] = GEN_INT (lane);
4211 operands[1] = gen_rtx_REG (<V_HALF>mode, regno);
4213 return "vst1.<V_sz_elem>\t{%P1}, [%0]";
4215 return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
4217 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4220 (define_insn "neon_vld2<mode>"
4221 [(set (match_operand:TI 0 "s_register_operand" "=w")
4222 (unspec:TI [(mem:TI (match_operand:SI 1 "s_register_operand" "r"))
4223 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4227 if (<V_sz_elem> == 64)
4228 return "vld1.64\t%h0, [%1]";
4230 return "vld2.<V_sz_elem>\t%h0, [%1]";
4232 [(set (attr "neon_type")
4233 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4234 (const_string "neon_vld1_1_2_regs")
4235 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))]
4238 (define_insn "neon_vld2<mode>"
4239 [(set (match_operand:OI 0 "s_register_operand" "=w")
4240 (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
4241 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4244 "vld2.<V_sz_elem>\t%h0, [%1]"
4245 [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")])
4247 (define_insn "neon_vld2_lane<mode>"
4248 [(set (match_operand:TI 0 "s_register_operand" "=w")
4249 (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4250 (match_operand:TI 2 "s_register_operand" "0")
4251 (match_operand:SI 3 "immediate_operand" "i")
4252 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4256 HOST_WIDE_INT lane = INTVAL (operands[3]);
4257 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4258 int regno = REGNO (operands[0]);
4260 if (lane < 0 || lane >= max)
4261 error ("lane out of range");
4262 ops[0] = gen_rtx_REG (DImode, regno);
4263 ops[1] = gen_rtx_REG (DImode, regno + 2);
4264 ops[2] = operands[1];
4265 ops[3] = operands[3];
4266 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
4269 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4272 (define_insn "neon_vld2_lane<mode>"
4273 [(set (match_operand:OI 0 "s_register_operand" "=w")
4274 (unspec:OI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4275 (match_operand:OI 2 "s_register_operand" "0")
4276 (match_operand:SI 3 "immediate_operand" "i")
4277 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4281 HOST_WIDE_INT lane = INTVAL (operands[3]);
4282 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4283 int regno = REGNO (operands[0]);
4285 if (lane < 0 || lane >= max)
4286 error ("lane out of range");
4287 else if (lane >= max / 2)
4292 ops[0] = gen_rtx_REG (DImode, regno);
4293 ops[1] = gen_rtx_REG (DImode, regno + 4);
4294 ops[2] = operands[1];
4295 ops[3] = GEN_INT (lane);
4296 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
4299 [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4302 (define_insn "neon_vld2_dup<mode>"
4303 [(set (match_operand:TI 0 "s_register_operand" "=w")
4304 (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
4305 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4309 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4310 return "vld2.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
4312 return "vld1.<V_sz_elem>\t%h0, [%1]";
4314 [(set (attr "neon_type")
4315 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4316 (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4317 (const_string "neon_vld1_1_2_regs")))]
4320 (define_insn "neon_vst2<mode>"
4321 [(set (mem:TI (match_operand:SI 0 "s_register_operand" "r"))
4322 (unspec:TI [(match_operand:TI 1 "s_register_operand" "w")
4323 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4327 if (<V_sz_elem> == 64)
4328 return "vst1.64\t%h1, [%0]";
4330 return "vst2.<V_sz_elem>\t%h1, [%0]";
4332 [(set (attr "neon_type")
4333 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4334 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4335 (const_string "neon_vst1_1_2_regs_vst2_2_regs")))]
4338 (define_insn "neon_vst2<mode>"
4339 [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
4340 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4341 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4344 "vst2.<V_sz_elem>\t%h1, [%0]"
4345 [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]
4348 (define_insn "neon_vst2_lane<mode>"
4349 [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
4350 (unspec:<V_two_elem>
4351 [(match_operand:TI 1 "s_register_operand" "w")
4352 (match_operand:SI 2 "immediate_operand" "i")
4353 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4357 HOST_WIDE_INT lane = INTVAL (operands[2]);
4358 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4359 int regno = REGNO (operands[1]);
4361 if (lane < 0 || lane >= max)
4362 error ("lane out of range");
4363 ops[0] = operands[0];
4364 ops[1] = gen_rtx_REG (DImode, regno);
4365 ops[2] = gen_rtx_REG (DImode, regno + 2);
4366 ops[3] = operands[2];
4367 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
4370 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4373 (define_insn "neon_vst2_lane<mode>"
4374 [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
4375 (unspec:<V_two_elem>
4376 [(match_operand:OI 1 "s_register_operand" "w")
4377 (match_operand:SI 2 "immediate_operand" "i")
4378 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4382 HOST_WIDE_INT lane = INTVAL (operands[2]);
4383 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4384 int regno = REGNO (operands[1]);
4386 if (lane < 0 || lane >= max)
4387 error ("lane out of range");
4388 else if (lane >= max / 2)
4393 ops[0] = operands[0];
4394 ops[1] = gen_rtx_REG (DImode, regno);
4395 ops[2] = gen_rtx_REG (DImode, regno + 4);
4396 ops[3] = GEN_INT (lane);
4397 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
4400 [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4403 (define_insn "neon_vld3<mode>"
4404 [(set (match_operand:EI 0 "s_register_operand" "=w")
4405 (unspec:EI [(mem:EI (match_operand:SI 1 "s_register_operand" "r"))
4406 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4410 if (<V_sz_elem> == 64)
4411 return "vld1.64\t%h0, [%1]";
4413 return "vld3.<V_sz_elem>\t%h0, [%1]";
4415 [(set (attr "neon_type")
4416 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4417 (const_string "neon_vld1_1_2_regs")
4418 (const_string "neon_vld3_vld4")))]
4421 (define_expand "neon_vld3<mode>"
4422 [(match_operand:CI 0 "s_register_operand" "=w")
4423 (match_operand:SI 1 "s_register_operand" "+r")
4424 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4427 emit_insn (gen_neon_vld3qa<mode> (operands[0], operands[0],
4428 operands[1], operands[1]));
4429 emit_insn (gen_neon_vld3qb<mode> (operands[0], operands[0],
4430 operands[1], operands[1]));
4434 (define_insn "neon_vld3qa<mode>"
4435 [(set (match_operand:CI 0 "s_register_operand" "=w")
4436 (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
4437 (match_operand:CI 1 "s_register_operand" "0")
4438 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4440 (set (match_operand:SI 2 "s_register_operand" "=r")
4441 (plus:SI (match_dup 3)
4445 int regno = REGNO (operands[0]);
4447 ops[0] = gen_rtx_REG (DImode, regno);
4448 ops[1] = gen_rtx_REG (DImode, regno + 4);
4449 ops[2] = gen_rtx_REG (DImode, regno + 8);
4450 ops[3] = operands[2];
4451 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
4454 [(set_attr "neon_type" "neon_vld3_vld4")]
4457 (define_insn "neon_vld3qb<mode>"
4458 [(set (match_operand:CI 0 "s_register_operand" "=w")
4459 (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
4460 (match_operand:CI 1 "s_register_operand" "0")
4461 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4463 (set (match_operand:SI 2 "s_register_operand" "=r")
4464 (plus:SI (match_dup 3)
4468 int regno = REGNO (operands[0]);
4470 ops[0] = gen_rtx_REG (DImode, regno + 2);
4471 ops[1] = gen_rtx_REG (DImode, regno + 6);
4472 ops[2] = gen_rtx_REG (DImode, regno + 10);
4473 ops[3] = operands[2];
4474 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
4477 [(set_attr "neon_type" "neon_vld3_vld4")]
4480 (define_insn "neon_vld3_lane<mode>"
4481 [(set (match_operand:EI 0 "s_register_operand" "=w")
4482 (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4483 (match_operand:EI 2 "s_register_operand" "0")
4484 (match_operand:SI 3 "immediate_operand" "i")
4485 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4489 HOST_WIDE_INT lane = INTVAL (operands[3]);
4490 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4491 int regno = REGNO (operands[0]);
4493 if (lane < 0 || lane >= max)
4494 error ("lane out of range");
4495 ops[0] = gen_rtx_REG (DImode, regno);
4496 ops[1] = gen_rtx_REG (DImode, regno + 2);
4497 ops[2] = gen_rtx_REG (DImode, regno + 4);
4498 ops[3] = operands[1];
4499 ops[4] = operands[3];
4500 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
4504 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4507 (define_insn "neon_vld3_lane<mode>"
4508 [(set (match_operand:CI 0 "s_register_operand" "=w")
4509 (unspec:CI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4510 (match_operand:CI 2 "s_register_operand" "0")
4511 (match_operand:SI 3 "immediate_operand" "i")
4512 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4516 HOST_WIDE_INT lane = INTVAL (operands[3]);
4517 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4518 int regno = REGNO (operands[0]);
4520 if (lane < 0 || lane >= max)
4521 error ("lane out of range");
4522 else if (lane >= max / 2)
4527 ops[0] = gen_rtx_REG (DImode, regno);
4528 ops[1] = gen_rtx_REG (DImode, regno + 4);
4529 ops[2] = gen_rtx_REG (DImode, regno + 8);
4530 ops[3] = operands[1];
4531 ops[4] = GEN_INT (lane);
4532 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
4536 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4539 (define_insn "neon_vld3_dup<mode>"
4540 [(set (match_operand:EI 0 "s_register_operand" "=w")
4541 (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
4542 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4546 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4548 int regno = REGNO (operands[0]);
4550 ops[0] = gen_rtx_REG (DImode, regno);
4551 ops[1] = gen_rtx_REG (DImode, regno + 2);
4552 ops[2] = gen_rtx_REG (DImode, regno + 4);
4553 ops[3] = operands[1];
4554 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[], %P1[], %P2[]}, [%3]", ops);
4558 return "vld1.<V_sz_elem>\t%h0, [%1]";
4560 [(set (attr "neon_type")
4561 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4562 (const_string "neon_vld3_vld4_all_lanes")
4563 (const_string "neon_vld1_1_2_regs")))])
4565 (define_insn "neon_vst3<mode>"
4566 [(set (mem:EI (match_operand:SI 0 "s_register_operand" "r"))
4567 (unspec:EI [(match_operand:EI 1 "s_register_operand" "w")
4568 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4572 if (<V_sz_elem> == 64)
4573 return "vst1.64\t%h1, [%0]";
4575 return "vst3.<V_sz_elem>\t%h1, [%0]";
4577 [(set (attr "neon_type")
4578 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4579 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4580 (const_string "neon_vst2_4_regs_vst3_vst4")))])
4582 (define_expand "neon_vst3<mode>"
4583 [(match_operand:SI 0 "s_register_operand" "+r")
4584 (match_operand:CI 1 "s_register_operand" "w")
4585 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4588 emit_insn (gen_neon_vst3qa<mode> (operands[0], operands[0], operands[1]));
4589 emit_insn (gen_neon_vst3qb<mode> (operands[0], operands[0], operands[1]));
4593 (define_insn "neon_vst3qa<mode>"
4594 [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
4595 (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
4596 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4598 (set (match_operand:SI 0 "s_register_operand" "=r")
4599 (plus:SI (match_dup 1)
4603 int regno = REGNO (operands[2]);
4605 ops[0] = operands[0];
4606 ops[1] = gen_rtx_REG (DImode, regno);
4607 ops[2] = gen_rtx_REG (DImode, regno + 4);
4608 ops[3] = gen_rtx_REG (DImode, regno + 8);
4609 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
4612 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4615 (define_insn "neon_vst3qb<mode>"
4616 [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
4617 (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
4618 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4620 (set (match_operand:SI 0 "s_register_operand" "=r")
4621 (plus:SI (match_dup 1)
4625 int regno = REGNO (operands[2]);
4627 ops[0] = operands[0];
4628 ops[1] = gen_rtx_REG (DImode, regno + 2);
4629 ops[2] = gen_rtx_REG (DImode, regno + 6);
4630 ops[3] = gen_rtx_REG (DImode, regno + 10);
4631 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
4634 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4637 (define_insn "neon_vst3_lane<mode>"
4638 [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
4639 (unspec:<V_three_elem>
4640 [(match_operand:EI 1 "s_register_operand" "w")
4641 (match_operand:SI 2 "immediate_operand" "i")
4642 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4646 HOST_WIDE_INT lane = INTVAL (operands[2]);
4647 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4648 int regno = REGNO (operands[1]);
4650 if (lane < 0 || lane >= max)
4651 error ("lane out of range");
4652 ops[0] = operands[0];
4653 ops[1] = gen_rtx_REG (DImode, regno);
4654 ops[2] = gen_rtx_REG (DImode, regno + 2);
4655 ops[3] = gen_rtx_REG (DImode, regno + 4);
4656 ops[4] = operands[2];
4657 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
4661 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
4664 (define_insn "neon_vst3_lane<mode>"
4665 [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
4666 (unspec:<V_three_elem>
4667 [(match_operand:CI 1 "s_register_operand" "w")
4668 (match_operand:SI 2 "immediate_operand" "i")
4669 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4673 HOST_WIDE_INT lane = INTVAL (operands[2]);
4674 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4675 int regno = REGNO (operands[1]);
4677 if (lane < 0 || lane >= max)
4678 error ("lane out of range");
4679 else if (lane >= max / 2)
4684 ops[0] = operands[0];
4685 ops[1] = gen_rtx_REG (DImode, regno);
4686 ops[2] = gen_rtx_REG (DImode, regno + 4);
4687 ops[3] = gen_rtx_REG (DImode, regno + 8);
4688 ops[4] = GEN_INT (lane);
4689 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
4693 [(set_attr "neon_type" "neon_vst3_vst4_lane")])
4695 (define_insn "neon_vld4<mode>"
4696 [(set (match_operand:OI 0 "s_register_operand" "=w")
4697 (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
4698 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4702 if (<V_sz_elem> == 64)
4703 return "vld1.64\t%h0, [%1]";
4705 return "vld4.<V_sz_elem>\t%h0, [%1]";
4707 [(set (attr "neon_type")
4708 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4709 (const_string "neon_vld1_1_2_regs")
4710 (const_string "neon_vld3_vld4")))]
4713 (define_expand "neon_vld4<mode>"
4714 [(match_operand:XI 0 "s_register_operand" "=w")
4715 (match_operand:SI 1 "s_register_operand" "+r")
4716 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4719 emit_insn (gen_neon_vld4qa<mode> (operands[0], operands[0],
4720 operands[1], operands[1]));
4721 emit_insn (gen_neon_vld4qb<mode> (operands[0], operands[0],
4722 operands[1], operands[1]));
4726 (define_insn "neon_vld4qa<mode>"
4727 [(set (match_operand:XI 0 "s_register_operand" "=w")
4728 (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
4729 (match_operand:XI 1 "s_register_operand" "0")
4730 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4732 (set (match_operand:SI 2 "s_register_operand" "=r")
4733 (plus:SI (match_dup 3)
4737 int regno = REGNO (operands[0]);
4739 ops[0] = gen_rtx_REG (DImode, regno);
4740 ops[1] = gen_rtx_REG (DImode, regno + 4);
4741 ops[2] = gen_rtx_REG (DImode, regno + 8);
4742 ops[3] = gen_rtx_REG (DImode, regno + 12);
4743 ops[4] = operands[2];
4744 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
4747 [(set_attr "neon_type" "neon_vld3_vld4")]
4750 (define_insn "neon_vld4qb<mode>"
4751 [(set (match_operand:XI 0 "s_register_operand" "=w")
4752 (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
4753 (match_operand:XI 1 "s_register_operand" "0")
4754 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4756 (set (match_operand:SI 2 "s_register_operand" "=r")
4757 (plus:SI (match_dup 3)
4761 int regno = REGNO (operands[0]);
4763 ops[0] = gen_rtx_REG (DImode, regno + 2);
4764 ops[1] = gen_rtx_REG (DImode, regno + 6);
4765 ops[2] = gen_rtx_REG (DImode, regno + 10);
4766 ops[3] = gen_rtx_REG (DImode, regno + 14);
4767 ops[4] = operands[2];
4768 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
4771 [(set_attr "neon_type" "neon_vld3_vld4")]
4774 (define_insn "neon_vld4_lane<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 (match_operand:OI 2 "s_register_operand" "0")
4778 (match_operand:SI 3 "immediate_operand" "i")
4779 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4783 HOST_WIDE_INT lane = INTVAL (operands[3]);
4784 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4785 int regno = REGNO (operands[0]);
4787 if (lane < 0 || lane >= max)
4788 error ("lane out of range");
4789 ops[0] = gen_rtx_REG (DImode, regno);
4790 ops[1] = gen_rtx_REG (DImode, regno + 2);
4791 ops[2] = gen_rtx_REG (DImode, regno + 4);
4792 ops[3] = gen_rtx_REG (DImode, regno + 6);
4793 ops[4] = operands[1];
4794 ops[5] = operands[3];
4795 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
4799 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4802 (define_insn "neon_vld4_lane<mode>"
4803 [(set (match_operand:XI 0 "s_register_operand" "=w")
4804 (unspec:XI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
4805 (match_operand:XI 2 "s_register_operand" "0")
4806 (match_operand:SI 3 "immediate_operand" "i")
4807 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4811 HOST_WIDE_INT lane = INTVAL (operands[3]);
4812 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4813 int regno = REGNO (operands[0]);
4815 if (lane < 0 || lane >= max)
4816 error ("lane out of range");
4817 else if (lane >= max / 2)
4822 ops[0] = gen_rtx_REG (DImode, regno);
4823 ops[1] = gen_rtx_REG (DImode, regno + 4);
4824 ops[2] = gen_rtx_REG (DImode, regno + 8);
4825 ops[3] = gen_rtx_REG (DImode, regno + 12);
4826 ops[4] = operands[1];
4827 ops[5] = GEN_INT (lane);
4828 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
4832 [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4835 (define_insn "neon_vld4_dup<mode>"
4836 [(set (match_operand:OI 0 "s_register_operand" "=w")
4837 (unspec:OI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
4838 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4842 if (GET_MODE_NUNITS (<MODE>mode) > 1)
4844 int regno = REGNO (operands[0]);
4846 ops[0] = gen_rtx_REG (DImode, regno);
4847 ops[1] = gen_rtx_REG (DImode, regno + 2);
4848 ops[2] = gen_rtx_REG (DImode, regno + 4);
4849 ops[3] = gen_rtx_REG (DImode, regno + 6);
4850 ops[4] = operands[1];
4851 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[], %P1[], %P2[], %P3[]}, [%4]",
4856 return "vld1.<V_sz_elem>\t%h0, [%1]";
4858 [(set (attr "neon_type")
4859 (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4860 (const_string "neon_vld3_vld4_all_lanes")
4861 (const_string "neon_vld1_1_2_regs")))]
4864 (define_insn "neon_vst4<mode>"
4865 [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
4866 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4867 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4871 if (<V_sz_elem> == 64)
4872 return "vst1.64\t%h1, [%0]";
4874 return "vst4.<V_sz_elem>\t%h1, [%0]";
4876 [(set (attr "neon_type")
4877 (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4878 (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4879 (const_string "neon_vst2_4_regs_vst3_vst4")))]
4882 (define_expand "neon_vst4<mode>"
4883 [(match_operand:SI 0 "s_register_operand" "+r")
4884 (match_operand:XI 1 "s_register_operand" "w")
4885 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4888 emit_insn (gen_neon_vst4qa<mode> (operands[0], operands[0], operands[1]));
4889 emit_insn (gen_neon_vst4qb<mode> (operands[0], operands[0], operands[1]));
4893 (define_insn "neon_vst4qa<mode>"
4894 [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
4895 (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
4896 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4898 (set (match_operand:SI 0 "s_register_operand" "=r")
4899 (plus:SI (match_dup 1)
4903 int regno = REGNO (operands[2]);
4905 ops[0] = operands[0];
4906 ops[1] = gen_rtx_REG (DImode, regno);
4907 ops[2] = gen_rtx_REG (DImode, regno + 4);
4908 ops[3] = gen_rtx_REG (DImode, regno + 8);
4909 ops[4] = gen_rtx_REG (DImode, regno + 12);
4910 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
4913 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4916 (define_insn "neon_vst4qb<mode>"
4917 [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
4918 (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
4919 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4921 (set (match_operand:SI 0 "s_register_operand" "=r")
4922 (plus:SI (match_dup 1)
4926 int regno = REGNO (operands[2]);
4928 ops[0] = operands[0];
4929 ops[1] = gen_rtx_REG (DImode, regno + 2);
4930 ops[2] = gen_rtx_REG (DImode, regno + 6);
4931 ops[3] = gen_rtx_REG (DImode, regno + 10);
4932 ops[4] = gen_rtx_REG (DImode, regno + 14);
4933 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
4936 [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4939 (define_insn "neon_vst4_lane<mode>"
4940 [(set (mem:<V_four_elem> (match_operand:SI 0 "s_register_operand" "r"))
4941 (unspec:<V_four_elem>
4942 [(match_operand:OI 1 "s_register_operand" "w")
4943 (match_operand:SI 2 "immediate_operand" "i")
4944 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4948 HOST_WIDE_INT lane = INTVAL (operands[2]);
4949 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4950 int regno = REGNO (operands[1]);
4952 if (lane < 0 || lane >= max)
4953 error ("lane out of range");
4954 ops[0] = operands[0];
4955 ops[1] = gen_rtx_REG (DImode, regno);
4956 ops[2] = gen_rtx_REG (DImode, regno + 2);
4957 ops[3] = gen_rtx_REG (DImode, regno + 4);
4958 ops[4] = gen_rtx_REG (DImode, regno + 6);
4959 ops[5] = operands[2];
4960 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, [%0]",
4964 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
4967 (define_insn "neon_vst4_lane<mode>"
4968 [(set (mem:<V_four_elem> (match_operand:SI 0 "s_register_operand" "r"))
4969 (unspec:<V_four_elem>
4970 [(match_operand:XI 1 "s_register_operand" "w")
4971 (match_operand:SI 2 "immediate_operand" "i")
4972 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4976 HOST_WIDE_INT lane = INTVAL (operands[2]);
4977 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4978 int regno = REGNO (operands[1]);
4980 if (lane < 0 || lane >= max)
4981 error ("lane out of range");
4982 else if (lane >= max / 2)
4987 ops[0] = operands[0];
4988 ops[1] = gen_rtx_REG (DImode, regno);
4989 ops[2] = gen_rtx_REG (DImode, regno + 4);
4990 ops[3] = gen_rtx_REG (DImode, regno + 8);
4991 ops[4] = gen_rtx_REG (DImode, regno + 12);
4992 ops[5] = GEN_INT (lane);
4993 output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, [%0]",
4997 [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5000 (define_expand "neon_vand<mode>"
5001 [(match_operand:VDQX 0 "s_register_operand" "")
5002 (match_operand:VDQX 1 "s_register_operand" "")
5003 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5004 (match_operand:SI 3 "immediate_operand" "")]
5007 emit_insn (gen_and<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5011 (define_expand "neon_vorr<mode>"
5012 [(match_operand:VDQX 0 "s_register_operand" "")
5013 (match_operand:VDQX 1 "s_register_operand" "")
5014 (match_operand:VDQX 2 "neon_logic_op2" "")
5015 (match_operand:SI 3 "immediate_operand" "")]
5018 emit_insn (gen_ior<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5022 (define_expand "neon_veor<mode>"
5023 [(match_operand:VDQX 0 "s_register_operand" "")
5024 (match_operand:VDQX 1 "s_register_operand" "")
5025 (match_operand:VDQX 2 "s_register_operand" "")
5026 (match_operand:SI 3 "immediate_operand" "")]
5029 emit_insn (gen_xor<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5033 (define_expand "neon_vbic<mode>"
5034 [(match_operand:VDQX 0 "s_register_operand" "")
5035 (match_operand:VDQX 1 "s_register_operand" "")
5036 (match_operand:VDQX 2 "neon_logic_op2" "")
5037 (match_operand:SI 3 "immediate_operand" "")]
5040 emit_insn (gen_bic<mode>3_neon (operands[0], operands[1], operands[2]));
5044 (define_expand "neon_vorn<mode>"
5045 [(match_operand:VDQX 0 "s_register_operand" "")
5046 (match_operand:VDQX 1 "s_register_operand" "")
5047 (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5048 (match_operand:SI 3 "immediate_operand" "")]
5051 emit_insn (gen_orn<mode>3_neon (operands[0], operands[1], operands[2]));