1 ;; ARM NEON coprocessor Machine Description
2 ;; Copyright (C) 2006 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 2, 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 COPYING. If not, write to the Free
19 ;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 ;; Constants for unspecs.
24 [(UNSPEC_ASHIFT_SIGNED 65)
25 (UNSPEC_ASHIFT_UNSIGNED 66)
60 (UNSPEC_VLD1_LANE 101)
63 (UNSPEC_VLD2_LANE 104)
68 (UNSPEC_VLD3_LANE 109)
73 (UNSPEC_VLD4_LANE 114)
78 (UNSPEC_VMLA_LANE 119)
79 (UNSPEC_VMLAL_LANE 120)
82 (UNSPEC_VMLS_LANE 123)
83 (UNSPEC_VMLSL_LANE 124)
88 (UNSPEC_VMUL_LANE 129)
89 (UNSPEC_VMULL_LANE 130)
106 (UNSPEC_VQDMLAL_LANE 147)
108 (UNSPEC_VQDMLSL_LANE 149)
110 (UNSPEC_VQDMULH_LANE 151)
112 (UNSPEC_VQDMULL_LANE 153)
118 (UNSPEC_VQSHLU_N 159)
119 (UNSPEC_VQSHRN_N 160)
120 (UNSPEC_VQSHRUN_N 161)
129 (UNSPEC_VSET_LANE 170)
139 (UNSPEC_VST1_LANE 180)
141 (UNSPEC_VST2_LANE 182)
145 (UNSPEC_VST3_LANE 186)
149 (UNSPEC_VST4_LANE 190)
150 (UNSPEC_VSTRUCTDUMMY 191)
165 ;; Double-width vector modes.
166 (define_mode_macro VD [V8QI V4HI V2SI V2SF])
168 ;; Double-width vector modes plus 64-bit elements.
169 (define_mode_macro VDX [V8QI V4HI V2SI V2SF DI])
171 ;; Same, without floating-point elements.
172 (define_mode_macro VDI [V8QI V4HI V2SI])
174 ;; Quad-width vector modes.
175 (define_mode_macro VQ [V16QI V8HI V4SI V4SF])
177 ;; Quad-width vector modes plus 64-bit elements.
178 (define_mode_macro VQX [V16QI V8HI V4SI V4SF V2DI])
180 ;; Same, without floating-point elements.
181 (define_mode_macro VQI [V16QI V8HI V4SI])
183 ;; Same, with TImode added, for moves.
184 (define_mode_macro VQXMOV [V16QI V8HI V4SI V4SF V2DI TI])
186 ;; Opaque structure types wider than TImode.
187 (define_mode_macro VSTRUCT [EI OI CI XI])
189 ;; Number of instructions needed to load/store struct elements. FIXME!
190 (define_mode_attr V_slen [(EI "2") (OI "2") (CI "3") (XI "4")])
192 ;; Opaque structure types used in table lookups (except vtbl1/vtbx1).
193 (define_mode_macro VTAB [TI EI OI])
195 ;; vtbl<n> suffix for above modes.
196 (define_mode_attr VTAB_n [(TI "2") (EI "3") (OI "4")])
199 (define_mode_macro VW [V8QI V4HI V2SI])
202 (define_mode_macro VN [V8HI V4SI V2DI])
204 ;; All supported vector modes (except singleton DImode).
205 (define_mode_macro VDQ [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF V2DI])
207 ;; All supported vector modes (except those with 64-bit integer elements).
208 (define_mode_macro VDQW [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF])
210 ;; Supported integer vector modes (not 64 bit elements).
211 (define_mode_macro VDQIW [V8QI V16QI V4HI V8HI V2SI V4SI])
213 ;; Supported integer vector modes (not singleton DI)
214 (define_mode_macro VDQI [V8QI V16QI V4HI V8HI V2SI V4SI V2DI])
216 ;; Vector modes, including 64-bit integer elements.
217 (define_mode_macro VDQX [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF DI V2DI])
219 ;; Vector modes including 64-bit integer elements, but no floats.
220 (define_mode_macro VDQIX [V8QI V16QI V4HI V8HI V2SI V4SI DI V2DI])
222 ;; Vector modes for float->int conversions.
223 (define_mode_macro VCVTF [V2SF V4SF])
225 ;; Vector modes form int->float conversions.
226 (define_mode_macro VCVTI [V2SI V4SI])
228 ;; Vector modes for doubleword multiply-accumulate, etc. insns.
229 (define_mode_macro VMD [V4HI V2SI V2SF])
231 ;; Vector modes for quadword multiply-accumulate, etc. insns.
232 (define_mode_macro VMQ [V8HI V4SI V4SF])
234 ;; Above modes combined.
235 (define_mode_macro VMDQ [V4HI V2SI V2SF V8HI V4SI V4SF])
237 ;; As VMD, but integer modes only.
238 (define_mode_macro VMDI [V4HI V2SI])
240 ;; As VMQ, but integer modes only.
241 (define_mode_macro VMQI [V8HI V4SI])
243 ;; Above modes combined.
244 (define_mode_macro VMDQI [V4HI V2SI V8HI V4SI])
246 ;; Modes with 8-bit and 16-bit elements.
247 (define_mode_macro VX [V8QI V4HI V16QI V8HI])
249 ;; Modes with 8-bit elements.
250 (define_mode_macro VE [V8QI V16QI])
252 ;; Modes with 64-bit elements only.
253 (define_mode_macro V64 [DI V2DI])
255 ;; Modes with 32-bit elements only.
256 (define_mode_macro V32 [V2SI V2SF V4SI V4SF])
258 ;; (Opposite) mode to convert to/from for above conversions.
259 (define_mode_attr V_CVTTO [(V2SI "V2SF") (V2SF "V2SI")
260 (V4SI "V4SF") (V4SF "V4SI")])
262 ;; Define element mode for each vector mode.
263 (define_mode_attr V_elem [(V8QI "QI") (V16QI "QI")
264 (V4HI "HI") (V8HI "HI")
265 (V2SI "SI") (V4SI "SI")
266 (V2SF "SF") (V4SF "SF")
267 (DI "DI") (V2DI "DI")])
269 ;; Mode of pair of elements for each vector mode, to define transfer
270 ;; size for structure lane/dup loads and stores.
271 (define_mode_attr V_two_elem [(V8QI "HI") (V16QI "HI")
272 (V4HI "SI") (V8HI "SI")
273 (V2SI "V2SI") (V4SI "V2SI")
274 (V2SF "V2SF") (V4SF "V2SF")
275 (DI "V2DI") (V2DI "V2DI")])
277 ;; Similar, for three elements.
278 ;; ??? Should we define extra modes so that sizes of all three-element
279 ;; accesses can be accurately represented?
280 (define_mode_attr V_three_elem [(V8QI "SI") (V16QI "SI")
281 (V4HI "V4HI") (V8HI "V4HI")
282 (V2SI "V4SI") (V4SI "V4SI")
283 (V2SF "V4SF") (V4SF "V4SF")
284 (DI "EI") (V2DI "EI")])
286 ;; Similar, for four elements.
287 (define_mode_attr V_four_elem [(V8QI "SI") (V16QI "SI")
288 (V4HI "V4HI") (V8HI "V4HI")
289 (V2SI "V4SI") (V4SI "V4SI")
290 (V2SF "V4SF") (V4SF "V4SF")
291 (DI "OI") (V2DI "OI")])
293 ;; Register width from element mode
294 (define_mode_attr V_reg [(V8QI "P") (V16QI "q")
295 (V4HI "P") (V8HI "q")
296 (V2SI "P") (V4SI "q")
297 (V2SF "P") (V4SF "q")
298 (DI "P") (V2DI "q")])
300 ;; Wider modes with the same number of elements.
301 (define_mode_attr V_widen [(V8QI "V8HI") (V4HI "V4SI") (V2SI "V2DI")])
303 ;; Narrower modes with the same number of elements.
304 (define_mode_attr V_narrow [(V8HI "V8QI") (V4SI "V4HI") (V2DI "V2SI")])
306 ;; Modes with half the number of equal-sized elements.
307 (define_mode_attr V_HALF [(V16QI "V8QI") (V8HI "V4HI")
308 (V4SI "V2SI") (V4SF "V2SF")
311 ;; Same, but lower-case.
312 (define_mode_attr V_half [(V16QI "v8qi") (V8HI "v4hi")
313 (V4SI "v2si") (V4SF "v2sf")
316 ;; Modes with twice the number of equal-sized elements.
317 (define_mode_attr V_DOUBLE [(V8QI "V16QI") (V4HI "V8HI")
318 (V2SI "V4SI") (V2SF "V4SF")
321 ;; Same, but lower-case.
322 (define_mode_attr V_double [(V8QI "v16qi") (V4HI "v8hi")
323 (V2SI "v4si") (V2SF "v4sf")
326 ;; Modes with double-width elements.
327 (define_mode_attr V_double_width [(V8QI "V4HI") (V16QI "V8HI")
328 (V4HI "V2SI") (V8HI "V4SI")
329 (V2SI "DI") (V4SI "V2DI")])
331 ;; Mode of result of comparison operations (and bit-select operand 1).
332 (define_mode_attr V_cmp_result [(V8QI "V8QI") (V16QI "V16QI")
333 (V4HI "V4HI") (V8HI "V8HI")
334 (V2SI "V2SI") (V4SI "V4SI")
335 (V2SF "V2SI") (V4SF "V4SI")
336 (DI "DI") (V2DI "V2DI")])
338 ;; Get element type from double-width mode, for operations where we don't care
340 (define_mode_attr V_if_elem [(V8QI "i8") (V16QI "i8")
341 (V4HI "i16") (V8HI "i16")
342 (V2SI "i32") (V4SI "i32")
343 (DI "i64") (V2DI "i64")
344 (V2SF "f32") (V4SF "f32")])
346 ;; Same, but for operations which work on signed values.
347 (define_mode_attr V_s_elem [(V8QI "s8") (V16QI "s8")
348 (V4HI "s16") (V8HI "s16")
349 (V2SI "s32") (V4SI "s32")
350 (DI "s64") (V2DI "s64")
351 (V2SF "f32") (V4SF "f32")])
353 ;; Same, but for operations which work on unsigned values.
354 (define_mode_attr V_u_elem [(V8QI "u8") (V16QI "u8")
355 (V4HI "u16") (V8HI "u16")
356 (V2SI "u32") (V4SI "u32")
357 (DI "u64") (V2DI "u64")
358 (V2SF "f32") (V4SF "f32")])
360 ;; Element types for extraction of unsigned scalars.
361 (define_mode_attr V_uf_sclr [(V8QI "u8") (V16QI "u8")
362 (V4HI "u16") (V8HI "u16")
363 (V2SI "32") (V4SI "32")
364 (V2SF "32") (V4SF "32")])
366 (define_mode_attr V_sz_elem [(V8QI "8") (V16QI "8")
367 (V4HI "16") (V8HI "16")
368 (V2SI "32") (V4SI "32")
369 (DI "64") (V2DI "64")
370 (V2SF "32") (V4SF "32")])
372 ;; Element sizes for duplicating ARM registers to all elements of a vector.
373 (define_mode_attr VD_dup [(V8QI "8") (V4HI "16") (V2SI "32") (V2SF "32")])
375 ;; Opaque integer types for results of pair-forming intrinsics (vtrn, etc.)
376 (define_mode_attr V_PAIR [(V8QI "TI") (V16QI "OI")
377 (V4HI "TI") (V8HI "OI")
378 (V2SI "TI") (V4SI "OI")
379 (V2SF "TI") (V4SF "OI")
380 (DI "TI") (V2DI "OI")])
382 ;; Same, but lower-case.
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 ;; Operations on two halves of a quadword vector.
390 (define_code_macro vqh_ops [plus smin smax umin umax])
392 ;; Same, without unsigned variants (for use with *SFmode pattern).
393 (define_code_macro vqhs_ops [plus smin smax])
395 ;; Assembler mnemonics for above codes.
396 (define_code_attr VQH_mnem [(plus "vadd") (smin "vmin") (smax "vmax")
397 (umin "vmin") (umax "vmax")])
399 ;; Signs of above, where relevant.
400 (define_code_attr VQH_sign [(plus "i") (smin "s") (smax "s") (umin "u")
403 ;; Extra suffix on some 64-bit insn names (to avoid collision with standard
404 ;; names which we don't want to define).
405 (define_mode_attr V_suf64 [(V8QI "") (V16QI "")
409 (DI "_neon") (V2DI "")])
411 ;; Scalars to be presented to scalar multiplication instructions
412 ;; must satisfy the following constraints.
413 ;; 1. If the mode specifies 16-bit elements, the scalar must be in D0-D7.
414 ;; 2. If the mode specifies 32-bit elements, the scalar must be in D0-D15.
415 ;; This mode attribute is used to obtain the correct register constraints.
416 (define_mode_attr scalar_mul_constraint [(V4HI "x") (V2SI "t") (V2SF "t")
417 (V8HI "x") (V4SI "t") (V4SF "t")])
419 (define_insn "*neon_mov<mode>"
420 [(set (match_operand:VD 0 "nonimmediate_operand"
421 "=w,Uv,w, w, ?r,?w,?r,?r, ?Us")
422 (match_operand:VD 1 "general_operand"
423 " w,w, Dn,Uvi, w, r, r, Usi,r"))]
426 if (which_alternative == 2)
429 static char templ[40];
431 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
432 &operands[1], &width);
434 gcc_assert (is_valid != 0);
437 return "vmov.f32\t%P0, %1 @ <mode>";
439 sprintf (templ, "vmov.i%d\t%%P0, %%1 @ <mode>", width);
444 /* FIXME: If the memory layout is changed in big-endian mode, output_move_vfp
445 below must be changed to output_move_neon (which will use the
446 element/structure loads/stores), and the constraint changed to 'Un' instead
449 switch (which_alternative)
451 case 0: return "vmov\t%P0, %P1 @ <mode>";
452 case 1: case 3: return output_move_vfp (operands);
453 case 2: gcc_unreachable ();
454 case 4: return "vmov\t%Q0, %R0, %P1 @ <mode>";
455 case 5: return "vmov\t%P0, %Q1, %R1 @ <mode>";
456 default: return output_move_double (operands);
459 [(set_attr "type" "farith,f_stored,farith,f_loadd,f_2_r,r_2_f,*,load2,store2")
460 (set_attr "length" "4,4,4,4,4,4,8,8,8")
461 (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
462 (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
464 (define_insn "*neon_mov<mode>"
465 [(set (match_operand:VQXMOV 0 "nonimmediate_operand"
466 "=w,Un,w, w, ?r,?w,?r,?r, ?Us")
467 (match_operand:VQXMOV 1 "general_operand"
468 " w,w, Dn,Uni, w, r, r, Usi, r"))]
471 if (which_alternative == 2)
474 static char templ[40];
476 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
477 &operands[1], &width);
479 gcc_assert (is_valid != 0);
482 return "vmov.f32\t%q0, %1 @ <mode>";
484 sprintf (templ, "vmov.i%d\t%%q0, %%1 @ <mode>", width);
489 switch (which_alternative)
491 case 0: return "vmov\t%q0, %q1 @ <mode>";
492 case 1: case 3: return output_move_neon (operands);
493 case 2: gcc_unreachable ();
494 case 4: return "vmov\t%Q0, %R0, %e1 @ <mode>\;vmov\t%J0, %K0, %f1";
495 case 5: return "vmov\t%e0, %Q1, %R1 @ <mode>\;vmov\t%f0, %J1, %K1";
496 default: return output_move_quad (operands);
499 [(set_attr "type" "farith,f_stored,farith,f_loadd,f_2_r,r_2_f,*,load2,store2")
500 (set_attr "length" "4,8,4,8,8,8,16,8,16")
501 (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
502 (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
504 (define_expand "movti"
505 [(set (match_operand:TI 0 "nonimmediate_operand" "")
506 (match_operand:TI 1 "general_operand" ""))]
511 (define_expand "mov<mode>"
512 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "")
513 (match_operand:VSTRUCT 1 "general_operand" ""))]
518 (define_insn "*neon_mov<mode>"
519 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "=w,Ut,w")
520 (match_operand:VSTRUCT 1 "general_operand" " w,w, Ut"))]
523 switch (which_alternative)
526 case 1: case 2: return output_move_neon (operands);
527 default: gcc_unreachable ();
530 [(set_attr "length" "<V_slen>,<V_slen>,<V_slen>")])
533 [(set (match_operand:EI 0 "s_register_operand" "")
534 (match_operand:EI 1 "s_register_operand" ""))]
535 "TARGET_NEON && reload_completed"
536 [(set (match_dup 0) (match_dup 1))
537 (set (match_dup 2) (match_dup 3))]
539 int rdest = REGNO (operands[0]);
540 int rsrc = REGNO (operands[1]);
543 dest[0] = gen_rtx_REG (TImode, rdest);
544 src[0] = gen_rtx_REG (TImode, rsrc);
545 dest[1] = gen_rtx_REG (DImode, rdest + 4);
546 src[1] = gen_rtx_REG (DImode, rsrc + 4);
548 neon_disambiguate_copy (operands, dest, src, 2);
552 [(set (match_operand:OI 0 "s_register_operand" "")
553 (match_operand:OI 1 "s_register_operand" ""))]
554 "TARGET_NEON && reload_completed"
555 [(set (match_dup 0) (match_dup 1))
556 (set (match_dup 2) (match_dup 3))]
558 int rdest = REGNO (operands[0]);
559 int rsrc = REGNO (operands[1]);
562 dest[0] = gen_rtx_REG (TImode, rdest);
563 src[0] = gen_rtx_REG (TImode, rsrc);
564 dest[1] = gen_rtx_REG (TImode, rdest + 4);
565 src[1] = gen_rtx_REG (TImode, rsrc + 4);
567 neon_disambiguate_copy (operands, dest, src, 2);
571 [(set (match_operand:CI 0 "s_register_operand" "")
572 (match_operand:CI 1 "s_register_operand" ""))]
573 "TARGET_NEON && reload_completed"
574 [(set (match_dup 0) (match_dup 1))
575 (set (match_dup 2) (match_dup 3))
576 (set (match_dup 4) (match_dup 5))]
578 int rdest = REGNO (operands[0]);
579 int rsrc = REGNO (operands[1]);
582 dest[0] = gen_rtx_REG (TImode, rdest);
583 src[0] = gen_rtx_REG (TImode, rsrc);
584 dest[1] = gen_rtx_REG (TImode, rdest + 4);
585 src[1] = gen_rtx_REG (TImode, rsrc + 4);
586 dest[2] = gen_rtx_REG (TImode, rdest + 8);
587 src[2] = gen_rtx_REG (TImode, rsrc + 8);
589 neon_disambiguate_copy (operands, dest, src, 3);
593 [(set (match_operand:XI 0 "s_register_operand" "")
594 (match_operand:XI 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))
598 (set (match_dup 4) (match_dup 5))
599 (set (match_dup 6) (match_dup 7))]
601 int rdest = REGNO (operands[0]);
602 int rsrc = REGNO (operands[1]);
605 dest[0] = gen_rtx_REG (TImode, rdest);
606 src[0] = gen_rtx_REG (TImode, rsrc);
607 dest[1] = gen_rtx_REG (TImode, rdest + 4);
608 src[1] = gen_rtx_REG (TImode, rsrc + 4);
609 dest[2] = gen_rtx_REG (TImode, rdest + 8);
610 src[2] = gen_rtx_REG (TImode, rsrc + 8);
611 dest[3] = gen_rtx_REG (TImode, rdest + 12);
612 src[3] = gen_rtx_REG (TImode, rsrc + 12);
614 neon_disambiguate_copy (operands, dest, src, 4);
617 (define_insn "vec_set<mode>"
618 [(set (match_operand:VD 0 "s_register_operand" "+w")
620 (match_operand:VD 3 "s_register_operand" "0")
622 (match_operand:<V_elem> 1 "s_register_operand" "r"))
623 (ashift:SI (const_int 1)
624 (match_operand:SI 2 "immediate_operand" "i"))))]
626 "vmov%?.<V_uf_sclr>\t%P0[%c2], %1"
627 [(set_attr "predicable" "yes")])
629 (define_insn "vec_set<mode>"
630 [(set (match_operand:VQ 0 "s_register_operand" "+w")
632 (match_operand:VQ 3 "s_register_operand" "0")
634 (match_operand:<V_elem> 1 "s_register_operand" "r"))
635 (ashift:SI (const_int 1)
636 (match_operand:SI 2 "immediate_operand" "i"))))]
639 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
640 int elt = INTVAL (operands[2]) % half_elts;
641 int hi = (INTVAL (operands[2]) / half_elts) * 2;
642 int regno = REGNO (operands[0]);
644 operands[0] = gen_rtx_REG (<V_HALF>mode, regno + hi);
645 operands[2] = GEN_INT (elt);
647 return "vmov%?.<V_uf_sclr>\t%P0[%c2], %1";
649 [(set_attr "predicable" "yes")])
651 (define_insn "vec_setv2di"
652 [(set (match_operand:V2DI 0 "s_register_operand" "+w")
654 (match_operand:V2DI 3 "s_register_operand" "0")
656 (match_operand:DI 1 "s_register_operand" "r"))
657 (ashift:SI (const_int 1)
658 (match_operand:SI 2 "immediate_operand" "i"))))]
661 int regno = REGNO (operands[0]) + INTVAL (operands[2]);
663 operands[0] = gen_rtx_REG (DImode, regno);
665 return "vmov%?.64\t%P0, %Q1, %R1";
667 [(set_attr "predicable" "yes")])
669 (define_insn "vec_extract<mode>"
670 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
672 (match_operand:VD 1 "s_register_operand" "w")
673 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
675 "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]"
676 [(set_attr "predicable" "yes")])
678 (define_insn "vec_extract<mode>"
679 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
681 (match_operand:VQ 1 "s_register_operand" "w")
682 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
685 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
686 int elt = INTVAL (operands[2]) % half_elts;
687 int hi = (INTVAL (operands[2]) / half_elts) * 2;
688 int regno = REGNO (operands[1]);
690 operands[1] = gen_rtx_REG (<V_HALF>mode, regno + hi);
691 operands[2] = GEN_INT (elt);
693 return "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]";
695 [(set_attr "predicable" "yes")])
697 (define_insn "vec_extractv2di"
698 [(set (match_operand:DI 0 "s_register_operand" "=r")
700 (match_operand:V2DI 1 "s_register_operand" "w")
701 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
704 int regno = REGNO (operands[1]) + INTVAL (operands[2]);
706 operands[1] = gen_rtx_REG (DImode, regno);
708 return "vmov%?.64\t%Q0, %R0, %P1";
710 [(set_attr "predicable" "yes")])
712 (define_expand "vec_init<mode>"
713 [(match_operand:VDQ 0 "s_register_operand" "")
714 (match_operand 1 "" "")]
717 neon_expand_vector_init (operands[0], operands[1]);
721 ;; Doubleword and quadword arithmetic.
723 ;; NOTE: vadd/vsub and some other instructions also support 64-bit integer
724 ;; element size, which we could potentially use for "long long" operations. We
725 ;; don't want to do this at present though, because moving values from the
726 ;; vector unit to the ARM core is currently slow and 64-bit addition (etc.) is
727 ;; easy to do with ARM instructions anyway.
729 (define_insn "*add<mode>3_neon"
730 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
731 (plus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
732 (match_operand:VDQ 2 "s_register_operand" "w")))]
734 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
736 (define_insn "*sub<mode>3_neon"
737 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
738 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
739 (match_operand:VDQ 2 "s_register_operand" "w")))]
741 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
743 (define_insn "*mul<mode>3_neon"
744 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
745 (mult:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
746 (match_operand:VDQ 2 "s_register_operand" "w")))]
748 "vmul.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
750 (define_insn "ior<mode>3"
751 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
752 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
753 (match_operand:VDQ 2 "neon_logic_op2" "w,Dl")))]
756 switch (which_alternative)
758 case 0: return "vorr\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
759 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
760 <MODE>mode, 0, VALID_NEON_QREG_MODE (<MODE>mode));
761 default: gcc_unreachable ();
765 (define_insn "iordi3_neon"
766 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
767 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w,0")
768 (match_operand:DI 2 "neon_logic_op2" "w,Dl")]
772 switch (which_alternative)
774 case 0: return "vorr\t%P0, %P1, %P2";
775 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
776 DImode, 0, VALID_NEON_QREG_MODE (DImode));
777 default: gcc_unreachable ();
781 ;; The concrete forms of the Neon immediate-logic instructions are vbic and
782 ;; vorr. We support the pseudo-instruction vand instead, because that
783 ;; corresponds to the canonical form the middle-end expects to use for
784 ;; immediate bitwise-ANDs.
786 (define_insn "and<mode>3"
787 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
788 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
789 (match_operand:VDQ 2 "neon_inv_logic_op2" "w,DL")))]
792 switch (which_alternative)
794 case 0: return "vand\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
795 case 1: return neon_output_logic_immediate ("vand", &operands[2],
796 <MODE>mode, 1, VALID_NEON_QREG_MODE (<MODE>mode));
797 default: gcc_unreachable ();
801 (define_insn "anddi3_neon"
802 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
803 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w,0")
804 (match_operand:DI 2 "neon_inv_logic_op2" "w,DL")]
808 switch (which_alternative)
810 case 0: return "vand\t%P0, %P1, %P2";
811 case 1: return neon_output_logic_immediate ("vand", &operands[2],
812 DImode, 1, VALID_NEON_QREG_MODE (DImode));
813 default: gcc_unreachable ();
817 (define_insn "orn<mode>3_neon"
818 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
819 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
820 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
822 "vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
824 (define_insn "orndi3_neon"
825 [(set (match_operand:DI 0 "s_register_operand" "=w")
826 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
827 (match_operand:DI 2 "s_register_operand" "w")]
830 "vorn\t%P0, %P1, %P2")
832 (define_insn "bic<mode>3_neon"
833 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
834 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
835 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
837 "vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
839 (define_insn "bicdi3_neon"
840 [(set (match_operand:DI 0 "s_register_operand" "=w")
841 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
842 (match_operand:DI 2 "s_register_operand" "w")]
845 "vbic\t%P0, %P1, %P2")
847 (define_insn "xor<mode>3"
848 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
849 (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
850 (match_operand:VDQ 2 "s_register_operand" "w")))]
852 "veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
854 (define_insn "xordi3_neon"
855 [(set (match_operand:DI 0 "s_register_operand" "=w")
856 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
857 (match_operand:DI 2 "s_register_operand" "w")]
860 "veor\t%P0, %P1, %P2")
862 (define_insn "one_cmpl<mode>2"
863 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
864 (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
866 "vmvn\t%<V_reg>0, %<V_reg>1")
868 (define_insn "abs<mode>2"
869 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
870 (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
872 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1")
874 (define_insn "neg<mode>2"
875 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
876 (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
878 "vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1")
880 (define_insn "*umin<mode>3_neon"
881 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
882 (umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
883 (match_operand:VDQIW 2 "s_register_operand" "w")))]
885 "vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
887 (define_insn "*umax<mode>3_neon"
888 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
889 (umax:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
890 (match_operand:VDQIW 2 "s_register_operand" "w")))]
892 "vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
894 (define_insn "*smin<mode>3_neon"
895 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
896 (smin:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
897 (match_operand:VDQW 2 "s_register_operand" "w")))]
899 "vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
901 (define_insn "*smax<mode>3_neon"
902 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
903 (smax:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
904 (match_operand:VDQW 2 "s_register_operand" "w")))]
906 "vmax.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
908 ; TODO: V2DI shifts are current disabled because there are bugs in the
909 ; generic vectorizer code. It ends up creating a V2DI constructor with
912 (define_insn "ashl<mode>3"
913 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
914 (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
915 (match_operand:VDQIW 2 "s_register_operand" "w")))]
917 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
919 ; Used for implementing logical shift-right, which is a left-shift by a negative
920 ; amount, with signed operands. This is essentially the same as ashl<mode>3
921 ; above, but using an unspec in case GCC tries anything tricky with negative
924 (define_insn "ashl<mode>3_signed"
925 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
926 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
927 (match_operand:VDQI 2 "s_register_operand" "w")]
928 UNSPEC_ASHIFT_SIGNED))]
930 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
932 ; Used for implementing logical shift-right, which is a left-shift by a negative
933 ; amount, with unsigned operands.
935 (define_insn "ashl<mode>3_unsigned"
936 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
937 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
938 (match_operand:VDQI 2 "s_register_operand" "w")]
939 UNSPEC_ASHIFT_UNSIGNED))]
941 "vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
943 (define_expand "ashr<mode>3"
944 [(set (match_operand:VDQIW 0 "s_register_operand" "")
945 (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
946 (match_operand:VDQIW 2 "s_register_operand" "")))]
949 rtx neg = gen_reg_rtx (<MODE>mode);
951 emit_insn (gen_neg<mode>2 (neg, operands[2]));
952 emit_insn (gen_ashl<mode>3_signed (operands[0], operands[1], neg));
957 (define_expand "lshr<mode>3"
958 [(set (match_operand:VDQIW 0 "s_register_operand" "")
959 (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
960 (match_operand:VDQIW 2 "s_register_operand" "")))]
963 rtx neg = gen_reg_rtx (<MODE>mode);
965 emit_insn (gen_neg<mode>2 (neg, operands[2]));
966 emit_insn (gen_ashl<mode>3_unsigned (operands[0], operands[1], neg));
971 ;; Widening operations
973 (define_insn "widen_ssum<mode>3"
974 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
975 (plus:<V_widen> (sign_extend:<V_widen>
976 (match_operand:VW 1 "s_register_operand" "%w"))
977 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
979 "vaddw.<V_s_elem>\t%q0, %q2, %P1")
981 (define_insn "widen_usum<mode>3"
982 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
983 (plus:<V_widen> (zero_extend:<V_widen>
984 (match_operand:VW 1 "s_register_operand" "%w"))
985 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
987 "vaddw.<V_u_elem>\t%q0, %q2, %P1")
989 ;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
990 ;; shift-count granularity. That's good enough for the middle-end's current
993 (define_expand "vec_shr_<mode>"
994 [(match_operand:VDQ 0 "s_register_operand" "")
995 (match_operand:VDQ 1 "s_register_operand" "")
996 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1000 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1001 const int width = GET_MODE_BITSIZE (<MODE>mode);
1002 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1003 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1004 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1006 if (num_bits == width)
1008 emit_move_insn (operands[0], operands[1]);
1012 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1013 operands[0] = gen_lowpart (bvecmode, operands[0]);
1014 operands[1] = gen_lowpart (bvecmode, operands[1]);
1016 emit_insn (gen_ext (operands[0], operands[1], zero_reg,
1017 GEN_INT (num_bits / BITS_PER_UNIT)));
1021 (define_expand "vec_shl_<mode>"
1022 [(match_operand:VDQ 0 "s_register_operand" "")
1023 (match_operand:VDQ 1 "s_register_operand" "")
1024 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1028 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1029 const int width = GET_MODE_BITSIZE (<MODE>mode);
1030 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1031 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1032 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1036 emit_move_insn (operands[0], CONST0_RTX (<MODE>mode));
1040 num_bits = width - num_bits;
1042 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1043 operands[0] = gen_lowpart (bvecmode, operands[0]);
1044 operands[1] = gen_lowpart (bvecmode, operands[1]);
1046 emit_insn (gen_ext (operands[0], zero_reg, operands[1],
1047 GEN_INT (num_bits / BITS_PER_UNIT)));
1051 ;; Helpers for quad-word reduction operations
1053 ; Add (or smin, smax...) the low N/2 elements of the N-element vector
1054 ; operand[1] to the high N/2 elements of same. Put the result in operand[0], an
1055 ; N/2-element vector.
1057 (define_insn "quad_halves_<code>v4si"
1058 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
1060 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
1061 (parallel [(const_int 0) (const_int 1)]))
1062 (vec_select:V2SI (match_dup 1)
1063 (parallel [(const_int 2) (const_int 3)]))))]
1065 "<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1")
1067 (define_insn "quad_halves_<code>v4sf"
1068 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
1070 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
1071 (parallel [(const_int 0) (const_int 1)]))
1072 (vec_select:V2SF (match_dup 1)
1073 (parallel [(const_int 2) (const_int 3)]))))]
1075 "<VQH_mnem>.f32\t%P0, %e1, %f1")
1077 (define_insn "quad_halves_<code>v8hi"
1078 [(set (match_operand:V4HI 0 "s_register_operand" "+w")
1080 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
1081 (parallel [(const_int 0) (const_int 1)
1082 (const_int 2) (const_int 3)]))
1083 (vec_select:V4HI (match_dup 1)
1084 (parallel [(const_int 4) (const_int 5)
1085 (const_int 6) (const_int 7)]))))]
1087 "<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1")
1089 (define_insn "quad_halves_<code>v16qi"
1090 [(set (match_operand:V8QI 0 "s_register_operand" "+w")
1092 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
1093 (parallel [(const_int 0) (const_int 1)
1094 (const_int 2) (const_int 3)
1095 (const_int 4) (const_int 5)
1096 (const_int 6) (const_int 7)]))
1097 (vec_select:V8QI (match_dup 1)
1098 (parallel [(const_int 8) (const_int 9)
1099 (const_int 10) (const_int 11)
1100 (const_int 12) (const_int 13)
1101 (const_int 14) (const_int 15)]))))]
1103 "<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1")
1105 ; FIXME: We wouldn't need the following insns if we could write subregs of
1106 ; vector registers. Make an attempt at removing unnecessary moves, though
1107 ; we're really at the mercy of the register allocator.
1109 (define_insn "move_lo_quad_v4si"
1110 [(set (match_operand:V4SI 0 "s_register_operand" "+w")
1112 (match_operand:V2SI 1 "s_register_operand" "w")
1113 (vec_select:V2SI (match_dup 0)
1114 (parallel [(const_int 2) (const_int 3)]))))]
1117 int dest = REGNO (operands[0]);
1118 int src = REGNO (operands[1]);
1121 return "vmov\t%e0, %P1";
1126 (define_insn "move_lo_quad_v4sf"
1127 [(set (match_operand:V4SF 0 "s_register_operand" "+w")
1129 (match_operand:V2SF 1 "s_register_operand" "w")
1130 (vec_select:V2SF (match_dup 0)
1131 (parallel [(const_int 2) (const_int 3)]))))]
1134 int dest = REGNO (operands[0]);
1135 int src = REGNO (operands[1]);
1138 return "vmov\t%e0, %P1";
1143 (define_insn "move_lo_quad_v8hi"
1144 [(set (match_operand:V8HI 0 "s_register_operand" "+w")
1146 (match_operand:V4HI 1 "s_register_operand" "w")
1147 (vec_select:V4HI (match_dup 0)
1148 (parallel [(const_int 4) (const_int 5)
1149 (const_int 6) (const_int 7)]))))]
1152 int dest = REGNO (operands[0]);
1153 int src = REGNO (operands[1]);
1156 return "vmov\t%e0, %P1";
1161 (define_insn "move_lo_quad_v16qi"
1162 [(set (match_operand:V16QI 0 "s_register_operand" "+w")
1164 (match_operand:V8QI 1 "s_register_operand" "w")
1165 (vec_select:V8QI (match_dup 0)
1166 (parallel [(const_int 8) (const_int 9)
1167 (const_int 10) (const_int 11)
1168 (const_int 12) (const_int 13)
1169 (const_int 14) (const_int 15)]))))]
1172 int dest = REGNO (operands[0]);
1173 int src = REGNO (operands[1]);
1176 return "vmov\t%e0, %P1";
1181 ;; Reduction operations
1183 (define_expand "reduc_splus_<mode>"
1184 [(match_operand:VD 0 "s_register_operand" "")
1185 (match_operand:VD 1 "s_register_operand" "")]
1188 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1189 &gen_neon_vpadd_internal<mode>);
1193 (define_expand "reduc_splus_<mode>"
1194 [(match_operand:VQ 0 "s_register_operand" "")
1195 (match_operand:VQ 1 "s_register_operand" "")]
1198 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1199 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1201 emit_insn (gen_quad_halves_plus<mode> (step1, operands[1]));
1202 emit_insn (gen_reduc_splus_<V_half> (res_d, step1));
1203 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1208 (define_insn "reduc_splus_v2di"
1209 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1210 (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")]
1213 "vadd.i64\t%e0, %e1, %f1")
1215 ;; NEON does not distinguish between signed and unsigned addition except on
1216 ;; widening operations.
1217 (define_expand "reduc_uplus_<mode>"
1218 [(match_operand:VDQI 0 "s_register_operand" "")
1219 (match_operand:VDQI 1 "s_register_operand" "")]
1222 emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1]));
1226 (define_expand "reduc_smin_<mode>"
1227 [(match_operand:VD 0 "s_register_operand" "")
1228 (match_operand:VD 1 "s_register_operand" "")]
1231 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1232 &gen_neon_vpsmin<mode>);
1236 (define_expand "reduc_smin_<mode>"
1237 [(match_operand:VQ 0 "s_register_operand" "")
1238 (match_operand:VQ 1 "s_register_operand" "")]
1241 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1242 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1244 emit_insn (gen_quad_halves_smin<mode> (step1, operands[1]));
1245 emit_insn (gen_reduc_smin_<V_half> (res_d, step1));
1246 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1251 (define_expand "reduc_smax_<mode>"
1252 [(match_operand:VD 0 "s_register_operand" "")
1253 (match_operand:VD 1 "s_register_operand" "")]
1256 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1257 &gen_neon_vpsmax<mode>);
1261 (define_expand "reduc_smax_<mode>"
1262 [(match_operand:VQ 0 "s_register_operand" "")
1263 (match_operand:VQ 1 "s_register_operand" "")]
1266 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1267 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1269 emit_insn (gen_quad_halves_smax<mode> (step1, operands[1]));
1270 emit_insn (gen_reduc_smax_<V_half> (res_d, step1));
1271 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1276 (define_expand "reduc_umin_<mode>"
1277 [(match_operand:VDI 0 "s_register_operand" "")
1278 (match_operand:VDI 1 "s_register_operand" "")]
1281 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1282 &gen_neon_vpumin<mode>);
1286 (define_expand "reduc_umin_<mode>"
1287 [(match_operand:VQI 0 "s_register_operand" "")
1288 (match_operand:VQI 1 "s_register_operand" "")]
1291 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1292 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1294 emit_insn (gen_quad_halves_umin<mode> (step1, operands[1]));
1295 emit_insn (gen_reduc_umin_<V_half> (res_d, step1));
1296 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1301 (define_expand "reduc_umax_<mode>"
1302 [(match_operand:VDI 0 "s_register_operand" "")
1303 (match_operand:VDI 1 "s_register_operand" "")]
1306 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1307 &gen_neon_vpumax<mode>);
1311 (define_expand "reduc_umax_<mode>"
1312 [(match_operand:VQI 0 "s_register_operand" "")
1313 (match_operand:VQI 1 "s_register_operand" "")]
1316 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1317 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1319 emit_insn (gen_quad_halves_umax<mode> (step1, operands[1]));
1320 emit_insn (gen_reduc_umax_<V_half> (res_d, step1));
1321 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1326 (define_insn "neon_vpadd_internal<mode>"
1327 [(set (match_operand:VD 0 "s_register_operand" "=w")
1328 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1329 (match_operand:VD 2 "s_register_operand" "w")]
1332 "vpadd.<V_if_elem>\t%P0, %P1, %P2")
1334 (define_insn "neon_vpsmin<mode>"
1335 [(set (match_operand:VD 0 "s_register_operand" "=w")
1336 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1337 (match_operand:VD 2 "s_register_operand" "w")]
1340 "vpmin.<V_s_elem>\t%P0, %P1, %P2")
1342 (define_insn "neon_vpsmax<mode>"
1343 [(set (match_operand:VD 0 "s_register_operand" "=w")
1344 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1345 (match_operand:VD 2 "s_register_operand" "w")]
1348 "vpmax.<V_s_elem>\t%P0, %P1, %P2")
1350 (define_insn "neon_vpumin<mode>"
1351 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1352 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1353 (match_operand:VDI 2 "s_register_operand" "w")]
1356 "vpmin.<V_u_elem>\t%P0, %P1, %P2")
1358 (define_insn "neon_vpumax<mode>"
1359 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1360 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1361 (match_operand:VDI 2 "s_register_operand" "w")]
1364 "vpmax.<V_u_elem>\t%P0, %P1, %P2")
1366 ;; Saturating arithmetic
1368 ; NOTE: Neon supports many more saturating variants of instructions than the
1369 ; following, but these are all GCC currently understands.
1370 ; FIXME: Actually, GCC doesn't know how to create saturating add/sub by itself
1371 ; yet either, although these patterns may be used by intrinsics when they're
1374 (define_insn "*ss_add<mode>_neon"
1375 [(set (match_operand:VD 0 "s_register_operand" "=w")
1376 (ss_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1377 (match_operand:VD 2 "s_register_operand" "w")))]
1379 "vqadd.<V_s_elem>\t%P0, %P1, %P2")
1381 (define_insn "*us_add<mode>_neon"
1382 [(set (match_operand:VD 0 "s_register_operand" "=w")
1383 (us_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1384 (match_operand:VD 2 "s_register_operand" "w")))]
1386 "vqadd.<V_u_elem>\t%P0, %P1, %P2")
1388 (define_insn "*ss_sub<mode>_neon"
1389 [(set (match_operand:VD 0 "s_register_operand" "=w")
1390 (ss_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1391 (match_operand:VD 2 "s_register_operand" "w")))]
1393 "vqsub.<V_s_elem>\t%P0, %P1, %P2")
1395 (define_insn "*us_sub<mode>_neon"
1396 [(set (match_operand:VD 0 "s_register_operand" "=w")
1397 (us_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1398 (match_operand:VD 2 "s_register_operand" "w")))]
1400 "vqsub.<V_u_elem>\t%P0, %P1, %P2")
1402 ;; Patterns for builtins.
1404 ; good for plain vadd, vaddq.
1406 (define_insn "neon_vadd<mode>"
1407 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1408 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1409 (match_operand:VDQX 2 "s_register_operand" "w")
1410 (match_operand:SI 3 "immediate_operand" "i")]
1413 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1415 ; operand 3 represents in bits:
1416 ; bit 0: signed (vs unsigned).
1417 ; bit 1: rounding (vs none).
1419 (define_insn "neon_vaddl<mode>"
1420 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1421 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1422 (match_operand:VDI 2 "s_register_operand" "w")
1423 (match_operand:SI 3 "immediate_operand" "i")]
1426 "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2")
1428 (define_insn "neon_vaddw<mode>"
1429 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1430 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1431 (match_operand:VDI 2 "s_register_operand" "w")
1432 (match_operand:SI 3 "immediate_operand" "i")]
1435 "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2")
1439 (define_insn "neon_vhadd<mode>"
1440 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1441 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1442 (match_operand:VDQIW 2 "s_register_operand" "w")
1443 (match_operand:SI 3 "immediate_operand" "i")]
1446 "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1448 (define_insn "neon_vqadd<mode>"
1449 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1450 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1451 (match_operand:VDQIX 2 "s_register_operand" "w")
1452 (match_operand:SI 3 "immediate_operand" "i")]
1455 "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1457 (define_insn "neon_vaddhn<mode>"
1458 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
1459 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
1460 (match_operand:VN 2 "s_register_operand" "w")
1461 (match_operand:SI 3 "immediate_operand" "i")]
1464 "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2")
1466 (define_insn "neon_vmul<mode>"
1467 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1468 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1469 (match_operand:VDQW 2 "s_register_operand" "w")
1470 (match_operand:SI 3 "immediate_operand" "i")]
1473 "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1475 (define_insn "neon_vmla<mode>"
1476 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1477 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
1478 (match_operand:VDQW 2 "s_register_operand" "w")
1479 (match_operand:VDQW 3 "s_register_operand" "w")
1480 (match_operand:SI 4 "immediate_operand" "i")]
1483 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3")
1485 (define_insn "neon_vmlal<mode>"
1486 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1487 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1488 (match_operand:VW 2 "s_register_operand" "w")
1489 (match_operand:VW 3 "s_register_operand" "w")
1490 (match_operand:SI 4 "immediate_operand" "i")]
1493 "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3")
1495 (define_insn "neon_vmls<mode>"
1496 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1497 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
1498 (match_operand:VDQW 2 "s_register_operand" "w")
1499 (match_operand:VDQW 3 "s_register_operand" "w")
1500 (match_operand:SI 4 "immediate_operand" "i")]
1503 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3")
1505 (define_insn "neon_vmlsl<mode>"
1506 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1507 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1508 (match_operand:VW 2 "s_register_operand" "w")
1509 (match_operand:VW 3 "s_register_operand" "w")
1510 (match_operand:SI 4 "immediate_operand" "i")]
1513 "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3")
1515 (define_insn "neon_vqdmulh<mode>"
1516 [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
1517 (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
1518 (match_operand:VMDQI 2 "s_register_operand" "w")
1519 (match_operand:SI 3 "immediate_operand" "i")]
1522 "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1524 (define_insn "neon_vqdmlal<mode>"
1525 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1526 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1527 (match_operand:VMDI 2 "s_register_operand" "w")
1528 (match_operand:VMDI 3 "s_register_operand" "w")
1529 (match_operand:SI 4 "immediate_operand" "i")]
1532 "vqdmlal.<V_s_elem>\t%q0, %P2, %P3")
1534 (define_insn "neon_vqdmlsl<mode>"
1535 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1536 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1537 (match_operand:VMDI 2 "s_register_operand" "w")
1538 (match_operand:VMDI 3 "s_register_operand" "w")
1539 (match_operand:SI 4 "immediate_operand" "i")]
1542 "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3")
1544 (define_insn "neon_vmull<mode>"
1545 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1546 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
1547 (match_operand:VW 2 "s_register_operand" "w")
1548 (match_operand:SI 3 "immediate_operand" "i")]
1551 "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2")
1553 (define_insn "neon_vqdmull<mode>"
1554 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1555 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
1556 (match_operand:VMDI 2 "s_register_operand" "w")
1557 (match_operand:SI 3 "immediate_operand" "i")]
1560 "vqdmull.<V_s_elem>\t%q0, %P1, %P2")
1562 (define_insn "neon_vsub<mode>"
1563 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1564 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1565 (match_operand:VDQX 2 "s_register_operand" "w")
1566 (match_operand:SI 3 "immediate_operand" "i")]
1569 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1571 (define_insn "neon_vsubl<mode>"
1572 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1573 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1574 (match_operand:VDI 2 "s_register_operand" "w")
1575 (match_operand:SI 3 "immediate_operand" "i")]
1578 "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2")
1580 (define_insn "neon_vsubw<mode>"
1581 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1582 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1583 (match_operand:VDI 2 "s_register_operand" "w")
1584 (match_operand:SI 3 "immediate_operand" "i")]
1587 "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2")
1589 (define_insn "neon_vqsub<mode>"
1590 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1591 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1592 (match_operand:VDQIX 2 "s_register_operand" "w")
1593 (match_operand:SI 3 "immediate_operand" "i")]
1596 "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1598 (define_insn "neon_vhsub<mode>"
1599 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1600 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1601 (match_operand:VDQIW 2 "s_register_operand" "w")
1602 (match_operand:SI 3 "immediate_operand" "i")]
1605 "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1607 (define_insn "neon_vsubhn<mode>"
1608 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
1609 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
1610 (match_operand:VN 2 "s_register_operand" "w")
1611 (match_operand:SI 3 "immediate_operand" "i")]
1614 "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2")
1616 (define_insn "neon_vceq<mode>"
1617 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
1618 (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
1619 (match_operand:VDQW 2 "s_register_operand" "w")
1620 (match_operand:SI 3 "immediate_operand" "i")]
1623 "vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1625 (define_insn "neon_vcge<mode>"
1626 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
1627 (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
1628 (match_operand:VDQW 2 "s_register_operand" "w")
1629 (match_operand:SI 3 "immediate_operand" "i")]
1632 "vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1634 (define_insn "neon_vcgt<mode>"
1635 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
1636 (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
1637 (match_operand:VDQW 2 "s_register_operand" "w")
1638 (match_operand:SI 3 "immediate_operand" "i")]
1641 "vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1643 (define_insn "neon_vcage<mode>"
1644 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
1645 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
1646 (match_operand:VCVTF 2 "s_register_operand" "w")
1647 (match_operand:SI 3 "immediate_operand" "i")]
1650 "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1652 (define_insn "neon_vcagt<mode>"
1653 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
1654 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
1655 (match_operand:VCVTF 2 "s_register_operand" "w")
1656 (match_operand:SI 3 "immediate_operand" "i")]
1659 "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1661 (define_insn "neon_vtst<mode>"
1662 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1663 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1664 (match_operand:VDQIW 2 "s_register_operand" "w")
1665 (match_operand:SI 3 "immediate_operand" "i")]
1668 "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1670 (define_insn "neon_vabd<mode>"
1671 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1672 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1673 (match_operand:VDQW 2 "s_register_operand" "w")
1674 (match_operand:SI 3 "immediate_operand" "i")]
1677 "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1679 (define_insn "neon_vabdl<mode>"
1680 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1681 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
1682 (match_operand:VW 2 "s_register_operand" "w")
1683 (match_operand:SI 3 "immediate_operand" "i")]
1686 "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2")
1688 (define_insn "neon_vaba<mode>"
1689 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1690 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "0")
1691 (match_operand:VDQIW 2 "s_register_operand" "w")
1692 (match_operand:VDQIW 3 "s_register_operand" "w")
1693 (match_operand:SI 4 "immediate_operand" "i")]
1696 "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3")
1698 (define_insn "neon_vabal<mode>"
1699 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1700 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1701 (match_operand:VW 2 "s_register_operand" "w")
1702 (match_operand:VW 3 "s_register_operand" "w")
1703 (match_operand:SI 4 "immediate_operand" "i")]
1706 "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3")
1708 (define_insn "neon_vmax<mode>"
1709 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1710 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1711 (match_operand:VDQW 2 "s_register_operand" "w")
1712 (match_operand:SI 3 "immediate_operand" "i")]
1715 "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1717 (define_insn "neon_vmin<mode>"
1718 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1719 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1720 (match_operand:VDQW 2 "s_register_operand" "w")
1721 (match_operand:SI 3 "immediate_operand" "i")]
1724 "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1726 (define_expand "neon_vpadd<mode>"
1727 [(match_operand:VD 0 "s_register_operand" "=w")
1728 (match_operand:VD 1 "s_register_operand" "w")
1729 (match_operand:VD 2 "s_register_operand" "w")
1730 (match_operand:SI 3 "immediate_operand" "i")]
1733 emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1],
1738 (define_insn "neon_vpaddl<mode>"
1739 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
1740 (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")
1741 (match_operand:SI 2 "immediate_operand" "i")]
1744 "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1")
1746 (define_insn "neon_vpadal<mode>"
1747 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
1748 (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0")
1749 (match_operand:VDQIW 2 "s_register_operand" "w")
1750 (match_operand:SI 3 "immediate_operand" "i")]
1753 "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2")
1755 (define_insn "neon_vpmax<mode>"
1756 [(set (match_operand:VD 0 "s_register_operand" "=w")
1757 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1758 (match_operand:VD 2 "s_register_operand" "w")
1759 (match_operand:SI 3 "immediate_operand" "i")]
1762 "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1764 (define_insn "neon_vpmin<mode>"
1765 [(set (match_operand:VD 0 "s_register_operand" "=w")
1766 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1767 (match_operand:VD 2 "s_register_operand" "w")
1768 (match_operand:SI 3 "immediate_operand" "i")]
1771 "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1773 (define_insn "neon_vrecps<mode>"
1774 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
1775 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
1776 (match_operand:VCVTF 2 "s_register_operand" "w")
1777 (match_operand:SI 3 "immediate_operand" "i")]
1780 "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1782 (define_insn "neon_vrsqrts<mode>"
1783 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
1784 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
1785 (match_operand:VCVTF 2 "s_register_operand" "w")
1786 (match_operand:SI 3 "immediate_operand" "i")]
1789 "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1791 (define_insn "neon_vabs<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:SI 2 "immediate_operand" "i")]
1797 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1")
1799 (define_insn "neon_vqabs<mode>"
1800 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1801 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1802 (match_operand:SI 2 "immediate_operand" "i")]
1805 "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1")
1807 (define_expand "neon_vneg<mode>"
1808 [(match_operand:VDQW 0 "s_register_operand" "")
1809 (match_operand:VDQW 1 "s_register_operand" "")
1810 (match_operand:SI 2 "immediate_operand" "")]
1813 emit_insn (gen_neg<mode>2 (operands[0], operands[1]));
1817 (define_insn "neon_vqneg<mode>"
1818 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1819 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1820 (match_operand:SI 2 "immediate_operand" "i")]
1823 "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1")
1825 (define_insn "neon_vcls<mode>"
1826 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1827 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1828 (match_operand:SI 2 "immediate_operand" "i")]
1831 "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1")
1833 (define_insn "neon_vclz<mode>"
1834 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1835 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1836 (match_operand:SI 2 "immediate_operand" "i")]
1839 "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1")
1841 (define_insn "neon_vcnt<mode>"
1842 [(set (match_operand:VE 0 "s_register_operand" "=w")
1843 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
1844 (match_operand:SI 2 "immediate_operand" "i")]
1847 "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1")
1849 (define_insn "neon_vrecpe<mode>"
1850 [(set (match_operand:V32 0 "s_register_operand" "=w")
1851 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
1852 (match_operand:SI 2 "immediate_operand" "i")]
1855 "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1")
1857 (define_insn "neon_vrsqrte<mode>"
1858 [(set (match_operand:V32 0 "s_register_operand" "=w")
1859 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
1860 (match_operand:SI 2 "immediate_operand" "i")]
1863 "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1")
1865 (define_expand "neon_vmvn<mode>"
1866 [(match_operand:VDQIW 0 "s_register_operand" "")
1867 (match_operand:VDQIW 1 "s_register_operand" "")
1868 (match_operand:SI 2 "immediate_operand" "")]
1871 emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1]));
1875 ;; FIXME: 32-bit element sizes are a bit funky (should be output as .32 not
1876 ;; .u32), but the assembler should cope with that.
1878 (define_insn "neon_vget_lane<mode>"
1879 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
1880 (unspec:<V_elem> [(match_operand:VD 1 "s_register_operand" "w")
1881 (match_operand:SI 2 "immediate_operand" "i")
1882 (match_operand:SI 3 "immediate_operand" "i")]
1885 "vmov%?.%t3%#<V_sz_elem>\t%0, %P1[%c2]"
1886 [(set_attr "predicable" "yes")])
1888 ; Operand 2 (lane number) is ignored because we can only extract the zeroth lane
1889 ; with this insn. Operand 3 (info word) is ignored because it does nothing
1890 ; useful with 64-bit elements.
1892 (define_insn "neon_vget_lanedi"
1893 [(set (match_operand:DI 0 "s_register_operand" "=r")
1894 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
1895 (match_operand:SI 2 "immediate_operand" "i")
1896 (match_operand:SI 3 "immediate_operand" "i")]
1899 "vmov%?\t%Q0, %R0, %P1 @ di"
1900 [(set_attr "predicable" "yes")])
1902 (define_insn "neon_vget_lane<mode>"
1903 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
1904 (unspec:<V_elem> [(match_operand:VQ 1 "s_register_operand" "w")
1905 (match_operand:SI 2 "immediate_operand" "i")
1906 (match_operand:SI 3 "immediate_operand" "i")]
1911 int regno = REGNO (operands[1]);
1912 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
1913 unsigned int elt = INTVAL (operands[2]);
1915 ops[0] = operands[0];
1916 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
1917 ops[2] = GEN_INT (elt % halfelts);
1918 ops[3] = operands[3];
1919 output_asm_insn ("vmov%?.%t3%#<V_sz_elem>\t%0, %P1[%c2]", ops);
1923 [(set_attr "predicable" "yes")])
1925 (define_insn "neon_vget_lanev2di"
1926 [(set (match_operand:DI 0 "s_register_operand" "=r")
1927 (unspec:DI [(match_operand:V2DI 1 "s_register_operand" "w")
1928 (match_operand:SI 2 "immediate_operand" "i")
1929 (match_operand:SI 3 "immediate_operand" "i")]
1934 unsigned int regno = REGNO (operands[1]);
1935 unsigned int elt = INTVAL (operands[2]);
1937 ops[0] = operands[0];
1938 ops[1] = gen_rtx_REG (DImode, regno + 2 * elt);
1939 output_asm_insn ("vmov%?\t%Q0, %R0, %P1 @ v2di", ops);
1943 [(set_attr "predicable" "yes")])
1946 (define_insn "neon_vset_lane<mode>"
1947 [(set (match_operand:VD 0 "s_register_operand" "=w")
1948 (unspec:VD [(match_operand:<V_elem> 1 "s_register_operand" "r")
1949 (match_operand:VD 2 "s_register_operand" "0")
1950 (match_operand:SI 3 "immediate_operand" "i")]
1953 "vmov%?.<V_sz_elem>\t%P0[%c3], %1"
1954 [(set_attr "predicable" "yes")])
1956 ; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
1958 (define_insn "neon_vset_lanedi"
1959 [(set (match_operand:DI 0 "s_register_operand" "=w")
1960 (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")
1961 (match_operand:DI 2 "s_register_operand" "0")
1962 (match_operand:SI 3 "immediate_operand" "i")]
1965 "vmov%?\t%P0, %Q1, %R1 @ di"
1966 [(set_attr "predicable" "yes")])
1968 (define_insn "neon_vset_lane<mode>"
1969 [(set (match_operand:VQ 0 "s_register_operand" "=w")
1970 (unspec:VQ [(match_operand:<V_elem> 1 "s_register_operand" "r")
1971 (match_operand:VQ 2 "s_register_operand" "0")
1972 (match_operand:SI 3 "immediate_operand" "i")]
1977 unsigned int regno = REGNO (operands[0]);
1978 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
1979 unsigned int elt = INTVAL (operands[3]);
1981 ops[0] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
1982 ops[1] = operands[1];
1983 ops[2] = GEN_INT (elt % halfelts);
1984 output_asm_insn ("vmov%?.<V_sz_elem>\t%P0[%c2], %1", ops);
1988 [(set_attr "predicable" "yes")])
1990 (define_insn "neon_vset_lanev2di"
1991 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1992 (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "r")
1993 (match_operand:V2DI 2 "s_register_operand" "0")
1994 (match_operand:SI 3 "immediate_operand" "i")]
1999 unsigned int regno = REGNO (operands[0]);
2000 unsigned int elt = INTVAL (operands[3]);
2002 ops[0] = gen_rtx_REG (DImode, regno + 2 * elt);
2003 ops[1] = operands[1];
2004 output_asm_insn ("vmov%?\t%P0, %Q1, %R1 @ v2di", ops);
2008 [(set_attr "predicable" "yes")])
2010 (define_expand "neon_vcreate<mode>"
2011 [(match_operand:VDX 0 "s_register_operand" "")
2012 (match_operand:DI 1 "general_operand" "")]
2015 rtx src = gen_lowpart (<MODE>mode, operands[1]);
2016 emit_move_insn (operands[0], src);
2020 (define_insn "neon_vdup_n<mode>"
2021 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2022 (unspec:VDQW [(match_operand:<V_elem> 1 "s_register_operand" "r")]
2025 "vdup%?.<V_sz_elem>\t%<V_reg>0, %1"
2026 [(set_attr "predicable" "yes")])
2028 (define_insn "neon_vdup_ndi"
2029 [(set (match_operand:DI 0 "s_register_operand" "=w")
2030 (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")]
2033 "vmov%?\t%P0, %Q1, %R1"
2034 [(set_attr "predicable" "yes")])
2036 (define_insn "neon_vdup_nv2di"
2037 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2038 (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "r")]
2041 "vmov%?\t%e0, %Q1, %R1\;vmov%?\t%f0, %Q1, %R1"
2042 [(set_attr "predicable" "yes")
2043 (set_attr "length" "8")])
2045 (define_insn "neon_vdup_lane<mode>"
2046 [(set (match_operand:VD 0 "s_register_operand" "=w")
2047 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2048 (match_operand:SI 2 "immediate_operand" "i")]
2051 "vdup.<V_sz_elem>\t%P0, %P1[%c2]")
2053 (define_insn "neon_vdup_lane<mode>"
2054 [(set (match_operand:VQ 0 "s_register_operand" "=w")
2055 (unspec:VQ [(match_operand:<V_HALF> 1 "s_register_operand" "w")
2056 (match_operand:SI 2 "immediate_operand" "i")]
2059 "vdup.<V_sz_elem>\t%q0, %P1[%c2]")
2061 ; Scalar index is ignored, since only zero is valid here.
2062 (define_expand "neon_vdup_lanedi"
2063 [(set (match_operand:DI 0 "s_register_operand" "=w")
2064 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
2065 (match_operand:SI 2 "immediate_operand" "i")]
2069 emit_move_insn (operands[0], operands[1]);
2074 (define_insn "neon_vdup_lanev2di"
2075 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2076 (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "w")
2077 (match_operand:SI 2 "immediate_operand" "i")]
2080 "vmov\t%e0, %P1\;vmov\t%f0, %P1"
2081 [(set_attr "length" "8")])
2083 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
2085 ;; FIXME: A different implementation of this builtin could make it much
2086 ;; more likely that we wouldn't actually need to output anything (we could make
2087 ;; it so that the reg allocator puts things in the right places magically
2088 ;; instead). Lack of subregs for vectors makes that tricky though, I think.
2090 (define_insn "neon_vcombine<mode>"
2091 [(set (match_operand:<V_DOUBLE> 0 "s_register_operand" "=w")
2092 (unspec:<V_DOUBLE> [(match_operand:VDX 1 "s_register_operand" "w")
2093 (match_operand:VDX 2 "s_register_operand" "w")]
2097 int dest = REGNO (operands[0]);
2098 int src1 = REGNO (operands[1]);
2099 int src2 = REGNO (operands[2]);
2102 if (src1 == dest && src2 == dest + 2)
2104 else if (src2 == dest && src1 == dest + 2)
2105 /* Special case of reversed high/low parts. */
2106 return "vswp\t%P1, %P2";
2108 destlo = gen_rtx_REG (<MODE>mode, dest);
2110 if (!reg_overlap_mentioned_p (operands[2], destlo))
2112 /* Try to avoid unnecessary moves if part of the result is in the right
2115 output_asm_insn ("vmov\t%e0, %P1", operands);
2116 if (src2 != dest + 2)
2117 output_asm_insn ("vmov\t%f0, %P2", operands);
2121 if (src2 != dest + 2)
2122 output_asm_insn ("vmov\t%f0, %P2", operands);
2124 output_asm_insn ("vmov\t%e0, %P1", operands);
2129 [(set_attr "length" "8")])
2131 (define_insn "neon_vget_high<mode>"
2132 [(set (match_operand:<V_HALF> 0 "s_register_operand" "=w")
2133 (unspec:<V_HALF> [(match_operand:VQX 1 "s_register_operand" "w")]
2137 int dest = REGNO (operands[0]);
2138 int src = REGNO (operands[1]);
2140 if (dest != src + 2)
2141 return "vmov\t%P0, %f1";
2146 (define_insn "neon_vget_low<mode>"
2147 [(set (match_operand:<V_HALF> 0 "s_register_operand" "=w")
2148 (unspec:<V_HALF> [(match_operand:VQX 1 "s_register_operand" "w")]
2152 int dest = REGNO (operands[0]);
2153 int src = REGNO (operands[1]);
2156 return "vmov\t%P0, %e1";
2161 (define_insn "neon_vcvt<mode>"
2162 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2163 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
2164 (match_operand:SI 2 "immediate_operand" "i")]
2167 "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1")
2169 (define_insn "neon_vcvt<mode>"
2170 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2171 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
2172 (match_operand:SI 2 "immediate_operand" "i")]
2175 "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1")
2177 (define_insn "neon_vcvt_n<mode>"
2178 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2179 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
2180 (match_operand:SI 2 "immediate_operand" "i")
2181 (match_operand:SI 3 "immediate_operand" "i")]
2184 "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2")
2186 (define_insn "neon_vcvt_n<mode>"
2187 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2188 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
2189 (match_operand:SI 2 "immediate_operand" "i")
2190 (match_operand:SI 3 "immediate_operand" "i")]
2193 "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2")
2195 (define_insn "neon_vmovn<mode>"
2196 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2197 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2198 (match_operand:SI 2 "immediate_operand" "i")]
2201 "vmovn.<V_if_elem>\t%P0, %q1")
2203 (define_insn "neon_vqmovn<mode>"
2204 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2205 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2206 (match_operand:SI 2 "immediate_operand" "i")]
2209 "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1")
2211 (define_insn "neon_vqmovun<mode>"
2212 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2213 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2214 (match_operand:SI 2 "immediate_operand" "i")]
2217 "vqmovun.<V_s_elem>\t%P0, %q1")
2219 (define_insn "neon_vmovl<mode>"
2220 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2221 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2222 (match_operand:SI 2 "immediate_operand" "i")]
2225 "vmovl.%T2%#<V_sz_elem>\t%q0, %P1")
2227 (define_insn "neon_vmul_lane<mode>"
2228 [(set (match_operand:VMD 0 "s_register_operand" "=w")
2229 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
2230 (match_operand:VMD 2 "s_register_operand"
2231 "<scalar_mul_constraint>")
2232 (match_operand:SI 3 "immediate_operand" "i")
2233 (match_operand:SI 4 "immediate_operand" "i")]
2236 "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]")
2238 (define_insn "neon_vmul_lane<mode>"
2239 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
2240 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
2241 (match_operand:<V_HALF> 2 "s_register_operand"
2242 "<scalar_mul_constraint>")
2243 (match_operand:SI 3 "immediate_operand" "i")
2244 (match_operand:SI 4 "immediate_operand" "i")]
2247 "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]")
2249 (define_insn "neon_vmull_lane<mode>"
2250 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2251 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
2252 (match_operand:VMDI 2 "s_register_operand"
2253 "<scalar_mul_constraint>")
2254 (match_operand:SI 3 "immediate_operand" "i")
2255 (match_operand:SI 4 "immediate_operand" "i")]
2256 UNSPEC_VMULL_LANE))]
2258 "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]")
2260 (define_insn "neon_vqdmull_lane<mode>"
2261 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2262 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
2263 (match_operand:VMDI 2 "s_register_operand"
2264 "<scalar_mul_constraint>")
2265 (match_operand:SI 3 "immediate_operand" "i")
2266 (match_operand:SI 4 "immediate_operand" "i")]
2267 UNSPEC_VQDMULL_LANE))]
2269 "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]")
2271 (define_insn "neon_vqdmulh_lane<mode>"
2272 [(set (match_operand:VMQI 0 "s_register_operand" "=w")
2273 (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
2274 (match_operand:<V_HALF> 2 "s_register_operand"
2275 "<scalar_mul_constraint>")
2276 (match_operand:SI 3 "immediate_operand" "i")
2277 (match_operand:SI 4 "immediate_operand" "i")]
2278 UNSPEC_VQDMULH_LANE))]
2280 "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]")
2282 (define_insn "neon_vqdmulh_lane<mode>"
2283 [(set (match_operand:VMDI 0 "s_register_operand" "=w")
2284 (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
2285 (match_operand:VMDI 2 "s_register_operand"
2286 "<scalar_mul_constraint>")
2287 (match_operand:SI 3 "immediate_operand" "i")
2288 (match_operand:SI 4 "immediate_operand" "i")]
2289 UNSPEC_VQDMULH_LANE))]
2291 "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]")
2293 (define_insn "neon_vmla_lane<mode>"
2294 [(set (match_operand:VMD 0 "s_register_operand" "=w")
2295 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
2296 (match_operand:VMD 2 "s_register_operand" "w")
2297 (match_operand:VMD 3 "s_register_operand"
2298 "<scalar_mul_constraint>")
2299 (match_operand:SI 4 "immediate_operand" "i")
2300 (match_operand:SI 5 "immediate_operand" "i")]
2303 "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]")
2305 (define_insn "neon_vmla_lane<mode>"
2306 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
2307 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
2308 (match_operand:VMQ 2 "s_register_operand" "w")
2309 (match_operand:<V_HALF> 3 "s_register_operand"
2310 "<scalar_mul_constraint>")
2311 (match_operand:SI 4 "immediate_operand" "i")
2312 (match_operand:SI 5 "immediate_operand" "i")]
2315 "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]")
2317 (define_insn "neon_vmlal_lane<mode>"
2318 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2319 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2320 (match_operand:VMDI 2 "s_register_operand" "w")
2321 (match_operand:VMDI 3 "s_register_operand"
2322 "<scalar_mul_constraint>")
2323 (match_operand:SI 4 "immediate_operand" "i")
2324 (match_operand:SI 5 "immediate_operand" "i")]
2325 UNSPEC_VMLAL_LANE))]
2327 "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]")
2329 (define_insn "neon_vqdmlal_lane<mode>"
2330 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2331 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2332 (match_operand:VMDI 2 "s_register_operand" "w")
2333 (match_operand:VMDI 3 "s_register_operand"
2334 "<scalar_mul_constraint>")
2335 (match_operand:SI 4 "immediate_operand" "i")
2336 (match_operand:SI 5 "immediate_operand" "i")]
2337 UNSPEC_VQDMLAL_LANE))]
2339 "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]")
2341 (define_insn "neon_vmls_lane<mode>"
2342 [(set (match_operand:VMD 0 "s_register_operand" "=w")
2343 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
2344 (match_operand:VMD 2 "s_register_operand" "w")
2345 (match_operand:VMD 3 "s_register_operand"
2346 "<scalar_mul_constraint>")
2347 (match_operand:SI 4 "immediate_operand" "i")
2348 (match_operand:SI 5 "immediate_operand" "i")]
2351 "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]")
2353 (define_insn "neon_vmls_lane<mode>"
2354 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
2355 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
2356 (match_operand:VMQ 2 "s_register_operand" "w")
2357 (match_operand:<V_HALF> 3 "s_register_operand"
2358 "<scalar_mul_constraint>")
2359 (match_operand:SI 4 "immediate_operand" "i")
2360 (match_operand:SI 5 "immediate_operand" "i")]
2363 "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]")
2365 (define_insn "neon_vmlsl_lane<mode>"
2366 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2367 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2368 (match_operand:VMDI 2 "s_register_operand" "w")
2369 (match_operand:VMDI 3 "s_register_operand"
2370 "<scalar_mul_constraint>")
2371 (match_operand:SI 4 "immediate_operand" "i")
2372 (match_operand:SI 5 "immediate_operand" "i")]
2373 UNSPEC_VMLSL_LANE))]
2375 "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]")
2377 (define_insn "neon_vqdmlsl_lane<mode>"
2378 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2379 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2380 (match_operand:VMDI 2 "s_register_operand" "w")
2381 (match_operand:VMDI 3 "s_register_operand"
2382 "<scalar_mul_constraint>")
2383 (match_operand:SI 4 "immediate_operand" "i")
2384 (match_operand:SI 5 "immediate_operand" "i")]
2385 UNSPEC_VQDMLSL_LANE))]
2387 "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]")
2389 ; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
2390 ; core register into a temp register, then use a scalar taken from that. This
2391 ; isn't an optimal solution if e.g. the scalar has just been read from memory
2392 ; or extracted from another vector. The latter case it's currently better to
2393 ; use the "_lane" variant, and the former case can probably be implemented
2394 ; using vld1_lane, but that hasn't been done yet.
2396 (define_expand "neon_vmul_n<mode>"
2397 [(match_operand:VMD 0 "s_register_operand" "")
2398 (match_operand:VMD 1 "s_register_operand" "")
2399 (match_operand:<V_elem> 2 "s_register_operand" "")
2400 (match_operand:SI 3 "immediate_operand" "")]
2403 rtx tmp = gen_reg_rtx (<MODE>mode);
2404 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
2405 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
2406 const0_rtx, const0_rtx));
2410 (define_expand "neon_vmul_n<mode>"
2411 [(match_operand:VMQ 0 "s_register_operand" "")
2412 (match_operand:VMQ 1 "s_register_operand" "")
2413 (match_operand:<V_elem> 2 "s_register_operand" "")
2414 (match_operand:SI 3 "immediate_operand" "")]
2417 rtx tmp = gen_reg_rtx (<V_HALF>mode);
2418 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
2419 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
2420 const0_rtx, const0_rtx));
2424 (define_expand "neon_vmull_n<mode>"
2425 [(match_operand:<V_widen> 0 "s_register_operand" "")
2426 (match_operand:VMDI 1 "s_register_operand" "")
2427 (match_operand:<V_elem> 2 "s_register_operand" "")
2428 (match_operand:SI 3 "immediate_operand" "")]
2431 rtx tmp = gen_reg_rtx (<MODE>mode);
2432 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
2433 emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp,
2434 const0_rtx, operands[3]));
2438 (define_expand "neon_vqdmull_n<mode>"
2439 [(match_operand:<V_widen> 0 "s_register_operand" "")
2440 (match_operand:VMDI 1 "s_register_operand" "")
2441 (match_operand:<V_elem> 2 "s_register_operand" "")
2442 (match_operand:SI 3 "immediate_operand" "")]
2445 rtx tmp = gen_reg_rtx (<MODE>mode);
2446 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
2447 emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp,
2448 const0_rtx, const0_rtx));
2452 (define_expand "neon_vqdmulh_n<mode>"
2453 [(match_operand:VMDI 0 "s_register_operand" "")
2454 (match_operand:VMDI 1 "s_register_operand" "")
2455 (match_operand:<V_elem> 2 "s_register_operand" "")
2456 (match_operand:SI 3 "immediate_operand" "")]
2459 rtx tmp = gen_reg_rtx (<MODE>mode);
2460 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
2461 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
2462 const0_rtx, operands[3]));
2466 (define_expand "neon_vqdmulh_n<mode>"
2467 [(match_operand:VMQI 0 "s_register_operand" "")
2468 (match_operand:VMQI 1 "s_register_operand" "")
2469 (match_operand:<V_elem> 2 "s_register_operand" "")
2470 (match_operand:SI 3 "immediate_operand" "")]
2473 rtx tmp = gen_reg_rtx (<V_HALF>mode);
2474 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
2475 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
2476 const0_rtx, operands[3]));
2480 (define_expand "neon_vmla_n<mode>"
2481 [(match_operand:VMD 0 "s_register_operand" "")
2482 (match_operand:VMD 1 "s_register_operand" "")
2483 (match_operand:VMD 2 "s_register_operand" "")
2484 (match_operand:<V_elem> 3 "s_register_operand" "")
2485 (match_operand:SI 4 "immediate_operand" "")]
2488 rtx tmp = gen_reg_rtx (<MODE>mode);
2489 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
2490 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
2491 tmp, const0_rtx, operands[4]));
2495 (define_expand "neon_vmla_n<mode>"
2496 [(match_operand:VMQ 0 "s_register_operand" "")
2497 (match_operand:VMQ 1 "s_register_operand" "")
2498 (match_operand:VMQ 2 "s_register_operand" "")
2499 (match_operand:<V_elem> 3 "s_register_operand" "")
2500 (match_operand:SI 4 "immediate_operand" "")]
2503 rtx tmp = gen_reg_rtx (<V_HALF>mode);
2504 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
2505 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
2506 tmp, const0_rtx, operands[4]));
2510 (define_expand "neon_vmlal_n<mode>"
2511 [(match_operand:<V_widen> 0 "s_register_operand" "")
2512 (match_operand:<V_widen> 1 "s_register_operand" "")
2513 (match_operand:VMDI 2 "s_register_operand" "")
2514 (match_operand:<V_elem> 3 "s_register_operand" "")
2515 (match_operand:SI 4 "immediate_operand" "")]
2518 rtx tmp = gen_reg_rtx (<MODE>mode);
2519 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
2520 emit_insn (gen_neon_vmlal_lane<mode> (operands[0], operands[1], operands[2],
2521 tmp, const0_rtx, operands[4]));
2525 (define_expand "neon_vqdmlal_n<mode>"
2526 [(match_operand:<V_widen> 0 "s_register_operand" "")
2527 (match_operand:<V_widen> 1 "s_register_operand" "")
2528 (match_operand:VMDI 2 "s_register_operand" "")
2529 (match_operand:<V_elem> 3 "s_register_operand" "")
2530 (match_operand:SI 4 "immediate_operand" "")]
2533 rtx tmp = gen_reg_rtx (<MODE>mode);
2534 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
2535 emit_insn (gen_neon_vqdmlal_lane<mode> (operands[0], operands[1], operands[2],
2536 tmp, const0_rtx, operands[4]));
2540 (define_expand "neon_vmls_n<mode>"
2541 [(match_operand:VMD 0 "s_register_operand" "")
2542 (match_operand:VMD 1 "s_register_operand" "")
2543 (match_operand:VMD 2 "s_register_operand" "")
2544 (match_operand:<V_elem> 3 "s_register_operand" "")
2545 (match_operand:SI 4 "immediate_operand" "")]
2548 rtx tmp = gen_reg_rtx (<MODE>mode);
2549 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
2550 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
2551 tmp, const0_rtx, operands[4]));
2555 (define_expand "neon_vmls_n<mode>"
2556 [(match_operand:VMQ 0 "s_register_operand" "")
2557 (match_operand:VMQ 1 "s_register_operand" "")
2558 (match_operand:VMQ 2 "s_register_operand" "")
2559 (match_operand:<V_elem> 3 "s_register_operand" "")
2560 (match_operand:SI 4 "immediate_operand" "")]
2563 rtx tmp = gen_reg_rtx (<V_HALF>mode);
2564 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
2565 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
2566 tmp, const0_rtx, operands[4]));
2570 (define_expand "neon_vmlsl_n<mode>"
2571 [(match_operand:<V_widen> 0 "s_register_operand" "")
2572 (match_operand:<V_widen> 1 "s_register_operand" "")
2573 (match_operand:VMDI 2 "s_register_operand" "")
2574 (match_operand:<V_elem> 3 "s_register_operand" "")
2575 (match_operand:SI 4 "immediate_operand" "")]
2578 rtx tmp = gen_reg_rtx (<MODE>mode);
2579 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
2580 emit_insn (gen_neon_vmlsl_lane<mode> (operands[0], operands[1], operands[2],
2581 tmp, const0_rtx, operands[4]));
2585 (define_expand "neon_vqdmlsl_n<mode>"
2586 [(match_operand:<V_widen> 0 "s_register_operand" "")
2587 (match_operand:<V_widen> 1 "s_register_operand" "")
2588 (match_operand:VMDI 2 "s_register_operand" "")
2589 (match_operand:<V_elem> 3 "s_register_operand" "")
2590 (match_operand:SI 4 "immediate_operand" "")]
2593 rtx tmp = gen_reg_rtx (<MODE>mode);
2594 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
2595 emit_insn (gen_neon_vqdmlsl_lane<mode> (operands[0], operands[1], operands[2],
2596 tmp, const0_rtx, operands[4]));
2600 (define_insn "neon_vext<mode>"
2601 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
2602 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
2603 (match_operand:VDQX 2 "s_register_operand" "w")
2604 (match_operand:SI 3 "immediate_operand" "i")]
2607 "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3")
2609 (define_insn "neon_vrev64<mode>"
2610 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
2611 (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
2612 (match_operand:SI 2 "immediate_operand" "i")]
2615 "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1")
2617 (define_insn "neon_vrev32<mode>"
2618 [(set (match_operand:VX 0 "s_register_operand" "=w")
2619 (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")
2620 (match_operand:SI 2 "immediate_operand" "i")]
2623 "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1")
2625 (define_insn "neon_vrev16<mode>"
2626 [(set (match_operand:VE 0 "s_register_operand" "=w")
2627 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
2628 (match_operand:SI 2 "immediate_operand" "i")]
2631 "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1")
2633 ; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
2634 ; allocation. For an intrinsic of form:
2635 ; rD = vbsl_* (rS, rN, rM)
2636 ; We can use any of:
2637 ; vbsl rS, rN, rM (if D = S)
2638 ; vbit rD, rN, rS (if D = M, so 1-bits in rS choose bits from rN, else rM)
2639 ; vbif rD, rM, rS (if D = N, so 0-bits in rS choose bits from rM, else rN)
2641 (define_insn "neon_vbsl<mode>_internal"
2642 [(set (match_operand:VDQX 0 "s_register_operand" "=w,w,w")
2643 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" " 0,w,w")
2644 (match_operand:VDQX 2 "s_register_operand" " w,w,0")
2645 (match_operand:VDQX 3 "s_register_operand" " w,0,w")]
2649 vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3
2650 vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1
2651 vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1")
2653 (define_expand "neon_vbsl<mode>"
2654 [(set (match_operand:VDQX 0 "s_register_operand" "")
2655 (unspec:VDQX [(match_operand:<V_cmp_result> 1 "s_register_operand" "")
2656 (match_operand:VDQX 2 "s_register_operand" "")
2657 (match_operand:VDQX 3 "s_register_operand" "")]
2661 /* We can't alias operands together if they have different modes. */
2662 operands[1] = gen_lowpart (<MODE>mode, operands[1]);
2665 (define_insn "neon_vshl<mode>"
2666 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2667 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2668 (match_operand:VDQIX 2 "s_register_operand" "w")
2669 (match_operand:SI 3 "immediate_operand" "i")]
2672 "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
2674 (define_insn "neon_vqshl<mode>"
2675 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2676 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2677 (match_operand:VDQIX 2 "s_register_operand" "w")
2678 (match_operand:SI 3 "immediate_operand" "i")]
2681 "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
2683 (define_insn "neon_vshr_n<mode>"
2684 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2685 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2686 (match_operand:SI 2 "immediate_operand" "i")
2687 (match_operand:SI 3 "immediate_operand" "i")]
2690 "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2")
2692 (define_insn "neon_vshrn_n<mode>"
2693 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2694 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2695 (match_operand:SI 2 "immediate_operand" "i")
2696 (match_operand:SI 3 "immediate_operand" "i")]
2699 "v%O3shrn.<V_if_elem>\t%P0, %q1, %2")
2701 (define_insn "neon_vqshrn_n<mode>"
2702 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2703 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2704 (match_operand:SI 2 "immediate_operand" "i")
2705 (match_operand:SI 3 "immediate_operand" "i")]
2708 "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2")
2710 (define_insn "neon_vqshrun_n<mode>"
2711 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2712 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2713 (match_operand:SI 2 "immediate_operand" "i")
2714 (match_operand:SI 3 "immediate_operand" "i")]
2717 "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2")
2719 (define_insn "neon_vshl_n<mode>"
2720 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2721 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2722 (match_operand:SI 2 "immediate_operand" "i")
2723 (match_operand:SI 3 "immediate_operand" "i")]
2726 "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2")
2728 (define_insn "neon_vqshl_n<mode>"
2729 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2730 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2731 (match_operand:SI 2 "immediate_operand" "i")
2732 (match_operand:SI 3 "immediate_operand" "i")]
2735 "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2")
2737 (define_insn "neon_vqshlu_n<mode>"
2738 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2739 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2740 (match_operand:SI 2 "immediate_operand" "i")
2741 (match_operand:SI 3 "immediate_operand" "i")]
2744 "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2")
2746 (define_insn "neon_vshll_n<mode>"
2747 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2748 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2749 (match_operand:SI 2 "immediate_operand" "i")
2750 (match_operand:SI 3 "immediate_operand" "i")]
2753 "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2")
2755 (define_insn "neon_vsra_n<mode>"
2756 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2757 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
2758 (match_operand:VDQIX 2 "s_register_operand" "w")
2759 (match_operand:SI 3 "immediate_operand" "i")
2760 (match_operand:SI 4 "immediate_operand" "i")]
2763 "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3")
2765 (define_insn "neon_vsri_n<mode>"
2766 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2767 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
2768 (match_operand:VDQIX 2 "s_register_operand" "w")
2769 (match_operand:SI 3 "immediate_operand" "i")]
2772 "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3")
2774 (define_insn "neon_vsli_n<mode>"
2775 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2776 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
2777 (match_operand:VDQIX 2 "s_register_operand" "w")
2778 (match_operand:SI 3 "immediate_operand" "i")]
2781 "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3")
2783 (define_insn "neon_vtbl1v8qi"
2784 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2785 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")
2786 (match_operand:V8QI 2 "s_register_operand" "w")]
2789 "vtbl.8\t%P0, {%P1}, %P2")
2791 (define_insn "neon_vtbl2v8qi"
2792 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2793 (unspec:V8QI [(match_operand:TI 1 "s_register_operand" "w")
2794 (match_operand:V8QI 2 "s_register_operand" "w")]
2799 int tabbase = REGNO (operands[1]);
2801 ops[0] = operands[0];
2802 ops[1] = gen_rtx_REG (V8QImode, tabbase);
2803 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
2804 ops[3] = operands[2];
2805 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2}, %P3", ops);
2810 (define_insn "neon_vtbl3v8qi"
2811 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2812 (unspec:V8QI [(match_operand:EI 1 "s_register_operand" "w")
2813 (match_operand:V8QI 2 "s_register_operand" "w")]
2818 int tabbase = REGNO (operands[1]);
2820 ops[0] = operands[0];
2821 ops[1] = gen_rtx_REG (V8QImode, tabbase);
2822 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
2823 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
2824 ops[4] = operands[2];
2825 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
2830 (define_insn "neon_vtbl4v8qi"
2831 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2832 (unspec:V8QI [(match_operand:OI 1 "s_register_operand" "w")
2833 (match_operand:V8QI 2 "s_register_operand" "w")]
2838 int tabbase = REGNO (operands[1]);
2840 ops[0] = operands[0];
2841 ops[1] = gen_rtx_REG (V8QImode, tabbase);
2842 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
2843 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
2844 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
2845 ops[5] = operands[2];
2846 output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
2851 (define_insn "neon_vtbx1v8qi"
2852 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2853 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
2854 (match_operand:V8QI 2 "s_register_operand" "w")
2855 (match_operand:V8QI 3 "s_register_operand" "w")]
2858 "vtbx.8\t%P0, {%P2}, %P3")
2860 (define_insn "neon_vtbx2v8qi"
2861 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2862 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
2863 (match_operand:TI 2 "s_register_operand" "w")
2864 (match_operand:V8QI 3 "s_register_operand" "w")]
2869 int tabbase = REGNO (operands[2]);
2871 ops[0] = operands[0];
2872 ops[1] = gen_rtx_REG (V8QImode, tabbase);
2873 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
2874 ops[3] = operands[3];
2875 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2}, %P3", ops);
2880 (define_insn "neon_vtbx3v8qi"
2881 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2882 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
2883 (match_operand:EI 2 "s_register_operand" "w")
2884 (match_operand:V8QI 3 "s_register_operand" "w")]
2889 int tabbase = REGNO (operands[2]);
2891 ops[0] = operands[0];
2892 ops[1] = gen_rtx_REG (V8QImode, tabbase);
2893 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
2894 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
2895 ops[4] = operands[3];
2896 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
2901 (define_insn "neon_vtbx4v8qi"
2902 [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2903 (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
2904 (match_operand:OI 2 "s_register_operand" "w")
2905 (match_operand:V8QI 3 "s_register_operand" "w")]
2910 int tabbase = REGNO (operands[2]);
2912 ops[0] = operands[0];
2913 ops[1] = gen_rtx_REG (V8QImode, tabbase);
2914 ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
2915 ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
2916 ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
2917 ops[5] = operands[3];
2918 output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
2923 (define_insn "neon_vtrn<mode>_internal"
2924 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2925 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
2927 (set (match_operand:VDQW 2 "s_register_operand" "=w")
2928 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
2931 "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2")
2933 (define_expand "neon_vtrn<mode>"
2934 [(match_operand:SI 0 "s_register_operand" "r")
2935 (match_operand:VDQW 1 "s_register_operand" "w")
2936 (match_operand:VDQW 2 "s_register_operand" "w")]
2939 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vtrn<mode>_internal,
2940 operands[0], operands[1], operands[2]);
2944 (define_insn "neon_vzip<mode>_internal"
2945 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2946 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
2948 (set (match_operand:VDQW 2 "s_register_operand" "=w")
2949 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
2952 "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2")
2954 (define_expand "neon_vzip<mode>"
2955 [(match_operand:SI 0 "s_register_operand" "r")
2956 (match_operand:VDQW 1 "s_register_operand" "w")
2957 (match_operand:VDQW 2 "s_register_operand" "w")]
2960 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vzip<mode>_internal,
2961 operands[0], operands[1], operands[2]);
2965 (define_insn "neon_vuzp<mode>_internal"
2966 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2967 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
2969 (set (match_operand:VDQW 2 "s_register_operand" "=w")
2970 (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
2973 "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2")
2975 (define_expand "neon_vuzp<mode>"
2976 [(match_operand:SI 0 "s_register_operand" "r")
2977 (match_operand:VDQW 1 "s_register_operand" "w")
2978 (match_operand:VDQW 2 "s_register_operand" "w")]
2981 neon_emit_pair_result_insn (<MODE>mode, gen_neon_vuzp<mode>_internal,
2982 operands[0], operands[1], operands[2]);
2986 (define_expand "neon_vreinterpretv8qi<mode>"
2987 [(match_operand:V8QI 0 "s_register_operand" "")
2988 (match_operand:VDX 1 "s_register_operand" "")]
2991 neon_reinterpret (operands[0], operands[1]);
2995 (define_expand "neon_vreinterpretv4hi<mode>"
2996 [(match_operand:V4HI 0 "s_register_operand" "")
2997 (match_operand:VDX 1 "s_register_operand" "")]
3000 neon_reinterpret (operands[0], operands[1]);
3004 (define_expand "neon_vreinterpretv2si<mode>"
3005 [(match_operand:V2SI 0 "s_register_operand" "")
3006 (match_operand:VDX 1 "s_register_operand" "")]
3009 neon_reinterpret (operands[0], operands[1]);
3013 (define_expand "neon_vreinterpretv2sf<mode>"
3014 [(match_operand:V2SF 0 "s_register_operand" "")
3015 (match_operand:VDX 1 "s_register_operand" "")]
3018 neon_reinterpret (operands[0], operands[1]);
3022 (define_expand "neon_vreinterpretdi<mode>"
3023 [(match_operand:DI 0 "s_register_operand" "")
3024 (match_operand:VDX 1 "s_register_operand" "")]
3027 neon_reinterpret (operands[0], operands[1]);
3031 (define_expand "neon_vreinterpretv16qi<mode>"
3032 [(match_operand:V16QI 0 "s_register_operand" "")
3033 (match_operand:VQX 1 "s_register_operand" "")]
3036 neon_reinterpret (operands[0], operands[1]);
3040 (define_expand "neon_vreinterpretv8hi<mode>"
3041 [(match_operand:V8HI 0 "s_register_operand" "")
3042 (match_operand:VQX 1 "s_register_operand" "")]
3045 neon_reinterpret (operands[0], operands[1]);
3049 (define_expand "neon_vreinterpretv4si<mode>"
3050 [(match_operand:V4SI 0 "s_register_operand" "")
3051 (match_operand:VQX 1 "s_register_operand" "")]
3054 neon_reinterpret (operands[0], operands[1]);
3058 (define_expand "neon_vreinterpretv4sf<mode>"
3059 [(match_operand:V4SF 0 "s_register_operand" "")
3060 (match_operand:VQX 1 "s_register_operand" "")]
3063 neon_reinterpret (operands[0], operands[1]);
3067 (define_expand "neon_vreinterpretv2di<mode>"
3068 [(match_operand:V2DI 0 "s_register_operand" "")
3069 (match_operand:VQX 1 "s_register_operand" "")]
3072 neon_reinterpret (operands[0], operands[1]);
3076 (define_insn "neon_vld1<mode>"
3077 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
3078 (unspec:VDQX [(mem:VDQX (match_operand:SI 1 "s_register_operand" "r"))]
3081 "vld1.<V_sz_elem>\t%h0, [%1]")
3083 (define_insn "neon_vld1_lane<mode>"
3084 [(set (match_operand:VDX 0 "s_register_operand" "=w")
3085 (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
3086 (match_operand:VDX 2 "s_register_operand" "0")
3087 (match_operand:SI 3 "immediate_operand" "i")]
3091 HOST_WIDE_INT lane = INTVAL (operands[3]);
3092 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3093 if (lane < 0 || lane >= max)
3094 error ("lane out of range");
3096 return "vld1.<V_sz_elem>\t%P0, [%1]";
3098 return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
3101 (define_insn "neon_vld1_lane<mode>"
3102 [(set (match_operand:VQX 0 "s_register_operand" "=w")
3103 (unspec:VQX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
3104 (match_operand:VQX 2 "s_register_operand" "0")
3105 (match_operand:SI 3 "immediate_operand" "i")]
3109 HOST_WIDE_INT lane = INTVAL (operands[3]);
3110 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3111 int regno = REGNO (operands[0]);
3112 if (lane < 0 || lane >= max)
3113 error ("lane out of range");
3114 else if (lane >= max / 2)
3118 operands[3] = GEN_INT (lane);
3120 operands[0] = gen_rtx_REG (<V_HALF>mode, regno);
3122 return "vld1.<V_sz_elem>\t%P0, [%1]";
3124 return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
3127 (define_insn "neon_vld1_dup<mode>"
3128 [(set (match_operand:VDX 0 "s_register_operand" "=w")
3129 (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))]
3133 if (GET_MODE_NUNITS (<MODE>mode) > 1)
3134 return "vld1.<V_sz_elem>\t{%P0[]}, [%1]";
3136 return "vld1.<V_sz_elem>\t%h0, [%1]";
3139 (define_insn "neon_vld1_dup<mode>"
3140 [(set (match_operand:VQX 0 "s_register_operand" "=w")
3141 (unspec:VQX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))]
3145 if (GET_MODE_NUNITS (<MODE>mode) > 2)
3146 return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
3148 return "vld1.<V_sz_elem>\t%h0, [%1]";
3151 (define_insn "neon_vst1<mode>"
3152 [(set (mem:VDQX (match_operand:SI 0 "s_register_operand" "r"))
3153 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")]
3156 "vst1.<V_sz_elem>\t%h1, [%0]")
3158 (define_insn "neon_vst1_lane<mode>"
3159 [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
3160 (vec_select:<V_elem>
3161 (match_operand:VDX 1 "s_register_operand" "w")
3162 (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
3165 HOST_WIDE_INT lane = INTVAL (operands[2]);
3166 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3167 if (lane < 0 || lane >= max)
3168 error ("lane out of range");
3170 return "vst1.<V_sz_elem>\t{%P1}, [%0]";
3172 return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
3175 (define_insn "neon_vst1_lane<mode>"
3176 [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
3177 (vec_select:<V_elem>
3178 (match_operand:VQX 1 "s_register_operand" "w")
3179 (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
3182 HOST_WIDE_INT lane = INTVAL (operands[2]);
3183 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3184 int regno = REGNO (operands[1]);
3185 if (lane < 0 || lane >= max)
3186 error ("lane out of range");
3187 else if (lane >= max / 2)
3191 operands[2] = GEN_INT (lane);
3193 operands[1] = gen_rtx_REG (<V_HALF>mode, regno);
3195 return "vst1.<V_sz_elem>\t{%P1}, [%0]";
3197 return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
3200 (define_insn "neon_vld2<mode>"
3201 [(set (match_operand:TI 0 "s_register_operand" "=w")
3202 (unspec:TI [(mem:TI (match_operand:SI 1 "s_register_operand" "r"))
3203 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3207 if (<V_sz_elem> == 64)
3208 return "vld1.64\t%h0, [%1]";
3210 return "vld2.<V_sz_elem>\t%h0, [%1]";
3213 (define_insn "neon_vld2<mode>"
3214 [(set (match_operand:OI 0 "s_register_operand" "=w")
3215 (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
3216 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3219 "vld2.<V_sz_elem>\t%h0, [%1]")
3221 (define_insn "neon_vld2_lane<mode>"
3222 [(set (match_operand:TI 0 "s_register_operand" "=w")
3223 (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
3224 (match_operand:TI 2 "s_register_operand" "0")
3225 (match_operand:SI 3 "immediate_operand" "i")
3226 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3230 HOST_WIDE_INT lane = INTVAL (operands[3]);
3231 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3232 int regno = REGNO (operands[0]);
3234 if (lane < 0 || lane >= max)
3235 error ("lane out of range");
3236 ops[0] = gen_rtx_REG (DImode, regno);
3237 ops[1] = gen_rtx_REG (DImode, regno + 2);
3238 ops[2] = operands[1];
3239 ops[3] = operands[3];
3240 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
3244 (define_insn "neon_vld2_lane<mode>"
3245 [(set (match_operand:OI 0 "s_register_operand" "=w")
3246 (unspec:OI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
3247 (match_operand:OI 2 "s_register_operand" "0")
3248 (match_operand:SI 3 "immediate_operand" "i")
3249 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3253 HOST_WIDE_INT lane = INTVAL (operands[3]);
3254 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3255 int regno = REGNO (operands[0]);
3257 if (lane < 0 || lane >= max)
3258 error ("lane out of range");
3259 else if (lane >= max / 2)
3264 ops[0] = gen_rtx_REG (DImode, regno);
3265 ops[1] = gen_rtx_REG (DImode, regno + 4);
3266 ops[2] = operands[1];
3267 ops[3] = GEN_INT (lane);
3268 output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
3272 (define_insn "neon_vld2_dup<mode>"
3273 [(set (match_operand:TI 0 "s_register_operand" "=w")
3274 (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
3275 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3279 if (GET_MODE_NUNITS (<MODE>mode) > 1)
3280 return "vld2.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
3282 return "vld1.<V_sz_elem>\t%h0, [%1]";
3285 (define_insn "neon_vst2<mode>"
3286 [(set (mem:TI (match_operand:SI 0 "s_register_operand" "r"))
3287 (unspec:TI [(match_operand:TI 1 "s_register_operand" "w")
3288 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3292 if (<V_sz_elem> == 64)
3293 return "vst1.64\t%h1, [%0]";
3295 return "vst2.<V_sz_elem>\t%h1, [%0]";
3298 (define_insn "neon_vst2<mode>"
3299 [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
3300 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
3301 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3304 "vst2.<V_sz_elem>\t%h1, [%0]")
3306 (define_insn "neon_vst2_lane<mode>"
3307 [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
3308 (unspec:<V_two_elem>
3309 [(match_operand:TI 1 "s_register_operand" "w")
3310 (match_operand:SI 2 "immediate_operand" "i")
3311 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3315 HOST_WIDE_INT lane = INTVAL (operands[2]);
3316 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3317 int regno = REGNO (operands[1]);
3319 if (lane < 0 || lane >= max)
3320 error ("lane out of range");
3321 ops[0] = operands[0];
3322 ops[1] = gen_rtx_REG (DImode, regno);
3323 ops[2] = gen_rtx_REG (DImode, regno + 2);
3324 ops[3] = operands[2];
3325 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
3329 (define_insn "neon_vst2_lane<mode>"
3330 [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
3331 (unspec:<V_two_elem>
3332 [(match_operand:OI 1 "s_register_operand" "w")
3333 (match_operand:SI 2 "immediate_operand" "i")
3334 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3338 HOST_WIDE_INT lane = INTVAL (operands[2]);
3339 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3340 int regno = REGNO (operands[1]);
3342 if (lane < 0 || lane >= max)
3343 error ("lane out of range");
3344 else if (lane >= max / 2)
3349 ops[0] = operands[0];
3350 ops[1] = gen_rtx_REG (DImode, regno);
3351 ops[2] = gen_rtx_REG (DImode, regno + 4);
3352 ops[3] = GEN_INT (lane);
3353 output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
3357 (define_insn "neon_vld3<mode>"
3358 [(set (match_operand:EI 0 "s_register_operand" "=w")
3359 (unspec:EI [(mem:EI (match_operand:SI 1 "s_register_operand" "r"))
3360 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3364 if (<V_sz_elem> == 64)
3365 return "vld1.64\t%h0, [%1]";
3367 return "vld3.<V_sz_elem>\t%h0, [%1]";
3370 (define_expand "neon_vld3<mode>"
3371 [(match_operand:CI 0 "s_register_operand" "=w")
3372 (match_operand:SI 1 "s_register_operand" "+r")
3373 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3376 emit_insn (gen_neon_vld3qa<mode> (operands[0], operands[0],
3377 operands[1], operands[1]));
3378 emit_insn (gen_neon_vld3qb<mode> (operands[0], operands[0],
3379 operands[1], operands[1]));
3383 (define_insn "neon_vld3qa<mode>"
3384 [(set (match_operand:CI 0 "s_register_operand" "=w")
3385 (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
3386 (match_operand:CI 1 "s_register_operand" "0")
3387 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3389 (set (match_operand:SI 2 "s_register_operand" "=r")
3390 (plus:SI (match_dup 3)
3394 int regno = REGNO (operands[0]);
3396 ops[0] = gen_rtx_REG (DImode, regno);
3397 ops[1] = gen_rtx_REG (DImode, regno + 4);
3398 ops[2] = gen_rtx_REG (DImode, regno + 8);
3399 ops[3] = operands[2];
3400 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
3404 (define_insn "neon_vld3qb<mode>"
3405 [(set (match_operand:CI 0 "s_register_operand" "=w")
3406 (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
3407 (match_operand:CI 1 "s_register_operand" "0")
3408 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3410 (set (match_operand:SI 2 "s_register_operand" "=r")
3411 (plus:SI (match_dup 3)
3415 int regno = REGNO (operands[0]);
3417 ops[0] = gen_rtx_REG (DImode, regno + 2);
3418 ops[1] = gen_rtx_REG (DImode, regno + 6);
3419 ops[2] = gen_rtx_REG (DImode, regno + 10);
3420 ops[3] = operands[2];
3421 output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
3425 (define_insn "neon_vld3_lane<mode>"
3426 [(set (match_operand:EI 0 "s_register_operand" "=w")
3427 (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
3428 (match_operand:EI 2 "s_register_operand" "0")
3429 (match_operand:SI 3 "immediate_operand" "i")
3430 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3434 HOST_WIDE_INT lane = INTVAL (operands[3]);
3435 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3436 int regno = REGNO (operands[0]);
3438 if (lane < 0 || lane >= max)
3439 error ("lane out of range");
3440 ops[0] = gen_rtx_REG (DImode, regno);
3441 ops[1] = gen_rtx_REG (DImode, regno + 2);
3442 ops[2] = gen_rtx_REG (DImode, regno + 4);
3443 ops[3] = operands[1];
3444 ops[4] = operands[3];
3445 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
3450 (define_insn "neon_vld3_lane<mode>"
3451 [(set (match_operand:CI 0 "s_register_operand" "=w")
3452 (unspec:CI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
3453 (match_operand:CI 2 "s_register_operand" "0")
3454 (match_operand:SI 3 "immediate_operand" "i")
3455 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3459 HOST_WIDE_INT lane = INTVAL (operands[3]);
3460 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3461 int regno = REGNO (operands[0]);
3463 if (lane < 0 || lane >= max)
3464 error ("lane out of range");
3465 else if (lane >= max / 2)
3470 ops[0] = gen_rtx_REG (DImode, regno);
3471 ops[1] = gen_rtx_REG (DImode, regno + 4);
3472 ops[2] = gen_rtx_REG (DImode, regno + 8);
3473 ops[3] = operands[1];
3474 ops[4] = GEN_INT (lane);
3475 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
3480 (define_insn "neon_vld3_dup<mode>"
3481 [(set (match_operand:EI 0 "s_register_operand" "=w")
3482 (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
3483 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3487 if (GET_MODE_NUNITS (<MODE>mode) > 1)
3489 int regno = REGNO (operands[0]);
3491 ops[0] = gen_rtx_REG (DImode, regno);
3492 ops[1] = gen_rtx_REG (DImode, regno + 2);
3493 ops[2] = gen_rtx_REG (DImode, regno + 4);
3494 ops[3] = operands[1];
3495 output_asm_insn ("vld3.<V_sz_elem>\t{%P0[], %P1[], %P2[]}, [%3]", ops);
3499 return "vld1.<V_sz_elem>\t%h0, [%1]";
3502 (define_insn "neon_vst3<mode>"
3503 [(set (mem:EI (match_operand:SI 0 "s_register_operand" "r"))
3504 (unspec:EI [(match_operand:EI 1 "s_register_operand" "w")
3505 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3509 if (<V_sz_elem> == 64)
3510 return "vst1.64\t%h1, [%0]";
3512 return "vst3.<V_sz_elem>\t%h1, [%0]";
3515 (define_expand "neon_vst3<mode>"
3516 [(match_operand:SI 0 "s_register_operand" "+r")
3517 (match_operand:CI 1 "s_register_operand" "w")
3518 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3521 emit_insn (gen_neon_vst3qa<mode> (operands[0], operands[0], operands[1]));
3522 emit_insn (gen_neon_vst3qb<mode> (operands[0], operands[0], operands[1]));
3526 (define_insn "neon_vst3qa<mode>"
3527 [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
3528 (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
3529 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3531 (set (match_operand:SI 0 "s_register_operand" "=r")
3532 (plus:SI (match_dup 1)
3536 int regno = REGNO (operands[2]);
3538 ops[0] = operands[0];
3539 ops[1] = gen_rtx_REG (DImode, regno);
3540 ops[2] = gen_rtx_REG (DImode, regno + 4);
3541 ops[3] = gen_rtx_REG (DImode, regno + 8);
3542 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
3546 (define_insn "neon_vst3qb<mode>"
3547 [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
3548 (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
3549 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3551 (set (match_operand:SI 0 "s_register_operand" "=r")
3552 (plus:SI (match_dup 1)
3556 int regno = REGNO (operands[2]);
3558 ops[0] = operands[0];
3559 ops[1] = gen_rtx_REG (DImode, regno + 2);
3560 ops[2] = gen_rtx_REG (DImode, regno + 6);
3561 ops[3] = gen_rtx_REG (DImode, regno + 10);
3562 output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
3566 (define_insn "neon_vst3_lane<mode>"
3567 [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
3568 (unspec:<V_three_elem>
3569 [(match_operand:EI 1 "s_register_operand" "w")
3570 (match_operand:SI 2 "immediate_operand" "i")
3571 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3575 HOST_WIDE_INT lane = INTVAL (operands[2]);
3576 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3577 int regno = REGNO (operands[1]);
3579 if (lane < 0 || lane >= max)
3580 error ("lane out of range");
3581 ops[0] = operands[0];
3582 ops[1] = gen_rtx_REG (DImode, regno);
3583 ops[2] = gen_rtx_REG (DImode, regno + 2);
3584 ops[3] = gen_rtx_REG (DImode, regno + 4);
3585 ops[4] = operands[2];
3586 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
3591 (define_insn "neon_vst3_lane<mode>"
3592 [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
3593 (unspec:<V_three_elem>
3594 [(match_operand:CI 1 "s_register_operand" "w")
3595 (match_operand:SI 2 "immediate_operand" "i")
3596 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3600 HOST_WIDE_INT lane = INTVAL (operands[2]);
3601 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3602 int regno = REGNO (operands[1]);
3604 if (lane < 0 || lane >= max)
3605 error ("lane out of range");
3606 else if (lane >= max / 2)
3611 ops[0] = operands[0];
3612 ops[1] = gen_rtx_REG (DImode, regno);
3613 ops[2] = gen_rtx_REG (DImode, regno + 4);
3614 ops[3] = gen_rtx_REG (DImode, regno + 8);
3615 ops[4] = GEN_INT (lane);
3616 output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
3621 (define_insn "neon_vld4<mode>"
3622 [(set (match_operand:OI 0 "s_register_operand" "=w")
3623 (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
3624 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3628 if (<V_sz_elem> == 64)
3629 return "vld1.64\t%h0, [%1]";
3631 return "vld4.<V_sz_elem>\t%h0, [%1]";
3634 (define_expand "neon_vld4<mode>"
3635 [(match_operand:XI 0 "s_register_operand" "=w")
3636 (match_operand:SI 1 "s_register_operand" "+r")
3637 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3640 emit_insn (gen_neon_vld4qa<mode> (operands[0], operands[0],
3641 operands[1], operands[1]));
3642 emit_insn (gen_neon_vld4qb<mode> (operands[0], operands[0],
3643 operands[1], operands[1]));
3647 (define_insn "neon_vld4qa<mode>"
3648 [(set (match_operand:XI 0 "s_register_operand" "=w")
3649 (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
3650 (match_operand:XI 1 "s_register_operand" "0")
3651 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3653 (set (match_operand:SI 2 "s_register_operand" "=r")
3654 (plus:SI (match_dup 3)
3658 int regno = REGNO (operands[0]);
3660 ops[0] = gen_rtx_REG (DImode, regno);
3661 ops[1] = gen_rtx_REG (DImode, regno + 4);
3662 ops[2] = gen_rtx_REG (DImode, regno + 8);
3663 ops[3] = gen_rtx_REG (DImode, regno + 12);
3664 ops[4] = operands[2];
3665 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
3669 (define_insn "neon_vld4qb<mode>"
3670 [(set (match_operand:XI 0 "s_register_operand" "=w")
3671 (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
3672 (match_operand:XI 1 "s_register_operand" "0")
3673 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3675 (set (match_operand:SI 2 "s_register_operand" "=r")
3676 (plus:SI (match_dup 3)
3680 int regno = REGNO (operands[0]);
3682 ops[0] = gen_rtx_REG (DImode, regno + 2);
3683 ops[1] = gen_rtx_REG (DImode, regno + 6);
3684 ops[2] = gen_rtx_REG (DImode, regno + 10);
3685 ops[3] = gen_rtx_REG (DImode, regno + 14);
3686 ops[4] = operands[2];
3687 output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
3691 (define_insn "neon_vld4_lane<mode>"
3692 [(set (match_operand:OI 0 "s_register_operand" "=w")
3693 (unspec:OI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
3694 (match_operand:OI 2 "s_register_operand" "0")
3695 (match_operand:SI 3 "immediate_operand" "i")
3696 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3700 HOST_WIDE_INT lane = INTVAL (operands[3]);
3701 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3702 int regno = REGNO (operands[0]);
3704 if (lane < 0 || lane >= max)
3705 error ("lane out of range");
3706 ops[0] = gen_rtx_REG (DImode, regno);
3707 ops[1] = gen_rtx_REG (DImode, regno + 2);
3708 ops[2] = gen_rtx_REG (DImode, regno + 4);
3709 ops[3] = gen_rtx_REG (DImode, regno + 6);
3710 ops[4] = operands[1];
3711 ops[5] = operands[3];
3712 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
3717 (define_insn "neon_vld4_lane<mode>"
3718 [(set (match_operand:XI 0 "s_register_operand" "=w")
3719 (unspec:XI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
3720 (match_operand:XI 2 "s_register_operand" "0")
3721 (match_operand:SI 3 "immediate_operand" "i")
3722 (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3726 HOST_WIDE_INT lane = INTVAL (operands[3]);
3727 HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3728 int regno = REGNO (operands[0]);
3730 if (lane < 0 || lane >= max)
3731 error ("lane out of range");
3732 else if (lane >= max / 2)
3737 ops[0] = gen_rtx_REG (DImode, regno);
3738 ops[1] = gen_rtx_REG (DImode, regno + 4);
3739 ops[2] = gen_rtx_REG (DImode, regno + 8);
3740 ops[3] = gen_rtx_REG (DImode, regno + 12);
3741 ops[4] = operands[1];
3742 ops[5] = GEN_INT (lane);
3743 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
3748 (define_insn "neon_vld4_dup<mode>"
3749 [(set (match_operand:OI 0 "s_register_operand" "=w")
3750 (unspec:OI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
3751 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3755 if (GET_MODE_NUNITS (<MODE>mode) > 1)
3757 int regno = REGNO (operands[0]);
3759 ops[0] = gen_rtx_REG (DImode, regno);
3760 ops[1] = gen_rtx_REG (DImode, regno + 2);
3761 ops[2] = gen_rtx_REG (DImode, regno + 4);
3762 ops[3] = gen_rtx_REG (DImode, regno + 6);
3763 ops[4] = operands[1];
3764 output_asm_insn ("vld4.<V_sz_elem>\t{%P0[], %P1[], %P2[], %P3[]}, [%4]",
3769 return "vld1.<V_sz_elem>\t%h0, [%1]";
3772 (define_insn "neon_vst4<mode>"
3773 [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
3774 (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
3775 (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3779 if (<V_sz_elem> == 64)
3780 return "vst1.64\t%h1, [%0]";
3782 return "vst4.<V_sz_elem>\t%h1, [%0]";
3785 (define_expand "neon_vst4<mode>"
3786 [(match_operand:SI 0 "s_register_operand" "+r")
3787 (match_operand:XI 1 "s_register_operand" "w")
3788 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3791 emit_insn (gen_neon_vst4qa<mode> (operands[0], operands[0], operands[1]));
3792 emit_insn (gen_neon_vst4qb<mode> (operands[0], operands[0], operands[1]));
3796 (define_insn "neon_vst4qa<mode>"
3797 [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
3798 (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
3799 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3801 (set (match_operand:SI 0 "s_register_operand" "=r")
3802 (plus:SI (match_dup 1)
3806 int regno = REGNO (operands[2]);
3808 ops[0] = operands[0];
3809 ops[1] = gen_rtx_REG (DImode, regno);
3810 ops[2] = gen_rtx_REG (DImode, regno + 4);
3811 ops[3] = gen_rtx_REG (DImode, regno + 8);
3812 ops[4] = gen_rtx_REG (DImode, regno + 12);
3813 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
3817 (define_insn "neon_vst4qb<mode>"
3818 [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
3819 (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
3820 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3822 (set (match_operand:SI 0 "s_register_operand" "=r")
3823 (plus:SI (match_dup 1)
3827 int regno = REGNO (operands[2]);
3829 ops[0] = operands[0];
3830 ops[1] = gen_rtx_REG (DImode, regno + 2);
3831 ops[2] = gen_rtx_REG (DImode, regno + 6);
3832 ops[3] = gen_rtx_REG (DImode, regno + 10);
3833 ops[4] = gen_rtx_REG (DImode, regno + 14);
3834 output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
3838 (define_insn "neon_vst4_lane<mode>"
3839 [(set (mem:<V_four_elem> (match_operand:SI 0 "s_register_operand" "r"))
3840 (unspec:<V_four_elem>
3841 [(match_operand:OI 1 "s_register_operand" "w")
3842 (match_operand:SI 2 "immediate_operand" "i")
3843 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]