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 ;; Attribute used to permit string comparisons against <VQH_mnem> in
420 ;; neon_type attribute definitions.
421 (define_attr "vqh_mnem" "vadd,vmin,vmax" (const_string "vadd"))
423 ;; Classification of NEON instructions for scheduling purposes.
424 ;; Do not set this attribute and the "type" attribute together in
425 ;; any one instruction pattern.
426 (define_attr "neon_type"
437 neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
438 neon_mul_qqq_8_16_32_ddd_32,\
439 neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
440 neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
442 neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
443 neon_mla_qqq_32_qqd_32_scalar,\
444 neon_mul_ddd_16_scalar_32_16_long_scalar,\
445 neon_mul_qqd_32_scalar,\
446 neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\
451 neon_vqshl_vrshl_vqrshl_qqq,\
453 neon_fp_vadd_ddd_vabs_dd,\
454 neon_fp_vadd_qqq_vabs_qq,\
460 neon_fp_vmla_ddd_scalar,\
461 neon_fp_vmla_qqq_scalar,\
462 neon_fp_vrecps_vrsqrts_ddd,\
463 neon_fp_vrecps_vrsqrts_qqq,\
471 neon_vld2_2_regs_vld1_vld2_all_lanes,\
474 neon_vst1_1_2_regs_vst2_2_regs,\
476 neon_vst2_4_regs_vst3_vst4,\
478 neon_vld1_vld2_lane,\
479 neon_vld3_vld4_lane,\
480 neon_vst1_vst2_lane,\
481 neon_vst3_vst4_lane,\
482 neon_vld3_vld4_all_lanes,\
490 (const_string "none"))
492 ;; Predicates used for setting the above attribute.
494 (define_mode_attr Is_float_mode [(V8QI "false") (V16QI "false")
495 (V4HI "false") (V8HI "false")
496 (V2SI "false") (V4SI "false")
497 (V2SF "true") (V4SF "true")
498 (DI "false") (V2DI "false")])
500 (define_mode_attr Scalar_mul_8_16 [(V8QI "true") (V16QI "true")
501 (V4HI "true") (V8HI "true")
502 (V2SI "false") (V4SI "false")
503 (V2SF "false") (V4SF "false")
504 (DI "false") (V2DI "false")])
507 (define_mode_attr Is_d_reg [(V8QI "true") (V16QI "false")
508 (V4HI "true") (V8HI "false")
509 (V2SI "true") (V4SI "false")
510 (V2SF "true") (V4SF "false")
511 (DI "true") (V2DI "false")])
513 (define_mode_attr V_mode_nunits [(V8QI "8") (V16QI "16")
514 (V4HI "4") (V8HI "8")
515 (V2SI "2") (V4SI "4")
516 (V2SF "2") (V4SF "4")
517 (DI "1") (V2DI "2")])
519 (define_insn "*neon_mov<mode>"
520 [(set (match_operand:VD 0 "nonimmediate_operand"
521 "=w,Uv,w, w, ?r,?w,?r,?r, ?Us")
522 (match_operand:VD 1 "general_operand"
523 " w,w, Dn,Uvi, w, r, r, Usi,r"))]
526 if (which_alternative == 2)
529 static char templ[40];
531 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
532 &operands[1], &width);
534 gcc_assert (is_valid != 0);
537 return "vmov.f32\t%P0, %1 @ <mode>";
539 sprintf (templ, "vmov.i%d\t%%P0, %%1 @ <mode>", width);
544 /* FIXME: If the memory layout is changed in big-endian mode, output_move_vfp
545 below must be changed to output_move_neon (which will use the
546 element/structure loads/stores), and the constraint changed to 'Un' instead
549 switch (which_alternative)
551 case 0: return "vmov\t%P0, %P1 @ <mode>";
552 case 1: case 3: return output_move_vfp (operands);
553 case 2: gcc_unreachable ();
554 case 4: return "vmov\t%Q0, %R0, %P1 @ <mode>";
555 case 5: return "vmov\t%P0, %Q1, %R1 @ <mode>";
556 default: return output_move_double (operands);
559 [(set_attr "neon_type" "neon_int_1,*,neon_vmov,*,neon_mrrc,neon_mcr_2_mcrr,*,*,*")
560 (set_attr "type" "*,f_stored,*,f_loadd,*,*,alu,load2,store2")
561 (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
562 (set_attr "length" "4,4,4,4,4,4,8,8,8")
563 (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
564 (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
566 (define_insn "*neon_mov<mode>"
567 [(set (match_operand:VQXMOV 0 "nonimmediate_operand"
568 "=w,Un,w, w, ?r,?w,?r,?r, ?Us")
569 (match_operand:VQXMOV 1 "general_operand"
570 " w,w, Dn,Uni, w, r, r, Usi, r"))]
573 if (which_alternative == 2)
576 static char templ[40];
578 is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
579 &operands[1], &width);
581 gcc_assert (is_valid != 0);
584 return "vmov.f32\t%q0, %1 @ <mode>";
586 sprintf (templ, "vmov.i%d\t%%q0, %%1 @ <mode>", width);
591 switch (which_alternative)
593 case 0: return "vmov\t%q0, %q1 @ <mode>";
594 case 1: case 3: return output_move_neon (operands);
595 case 2: gcc_unreachable ();
596 case 4: return "vmov\t%Q0, %R0, %e1 @ <mode>\;vmov\t%J0, %K0, %f1";
597 case 5: return "vmov\t%e0, %Q1, %R1 @ <mode>\;vmov\t%f0, %J1, %K1";
598 default: return output_move_quad (operands);
601 [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\
602 neon_mrrc,neon_mcr_2_mcrr,*,*,*")
603 (set_attr "type" "*,*,*,*,*,*,alu,load4,store4")
604 (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
605 (set_attr "length" "4,8,4,8,8,8,16,8,16")
606 (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
607 (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
609 (define_expand "movti"
610 [(set (match_operand:TI 0 "nonimmediate_operand" "")
611 (match_operand:TI 1 "general_operand" ""))]
616 (define_expand "mov<mode>"
617 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "")
618 (match_operand:VSTRUCT 1 "general_operand" ""))]
623 (define_insn "*neon_mov<mode>"
624 [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "=w,Ut,w")
625 (match_operand:VSTRUCT 1 "general_operand" " w,w, Ut"))]
628 switch (which_alternative)
631 case 1: case 2: return output_move_neon (operands);
632 default: gcc_unreachable ();
635 [(set_attr "length" "<V_slen>,<V_slen>,<V_slen>")])
638 [(set (match_operand:EI 0 "s_register_operand" "")
639 (match_operand:EI 1 "s_register_operand" ""))]
640 "TARGET_NEON && reload_completed"
641 [(set (match_dup 0) (match_dup 1))
642 (set (match_dup 2) (match_dup 3))]
644 int rdest = REGNO (operands[0]);
645 int rsrc = REGNO (operands[1]);
648 dest[0] = gen_rtx_REG (TImode, rdest);
649 src[0] = gen_rtx_REG (TImode, rsrc);
650 dest[1] = gen_rtx_REG (DImode, rdest + 4);
651 src[1] = gen_rtx_REG (DImode, rsrc + 4);
653 neon_disambiguate_copy (operands, dest, src, 2);
657 [(set (match_operand:OI 0 "s_register_operand" "")
658 (match_operand:OI 1 "s_register_operand" ""))]
659 "TARGET_NEON && reload_completed"
660 [(set (match_dup 0) (match_dup 1))
661 (set (match_dup 2) (match_dup 3))]
663 int rdest = REGNO (operands[0]);
664 int rsrc = REGNO (operands[1]);
667 dest[0] = gen_rtx_REG (TImode, rdest);
668 src[0] = gen_rtx_REG (TImode, rsrc);
669 dest[1] = gen_rtx_REG (TImode, rdest + 4);
670 src[1] = gen_rtx_REG (TImode, rsrc + 4);
672 neon_disambiguate_copy (operands, dest, src, 2);
676 [(set (match_operand:CI 0 "s_register_operand" "")
677 (match_operand:CI 1 "s_register_operand" ""))]
678 "TARGET_NEON && reload_completed"
679 [(set (match_dup 0) (match_dup 1))
680 (set (match_dup 2) (match_dup 3))
681 (set (match_dup 4) (match_dup 5))]
683 int rdest = REGNO (operands[0]);
684 int rsrc = REGNO (operands[1]);
687 dest[0] = gen_rtx_REG (TImode, rdest);
688 src[0] = gen_rtx_REG (TImode, rsrc);
689 dest[1] = gen_rtx_REG (TImode, rdest + 4);
690 src[1] = gen_rtx_REG (TImode, rsrc + 4);
691 dest[2] = gen_rtx_REG (TImode, rdest + 8);
692 src[2] = gen_rtx_REG (TImode, rsrc + 8);
694 neon_disambiguate_copy (operands, dest, src, 3);
698 [(set (match_operand:XI 0 "s_register_operand" "")
699 (match_operand:XI 1 "s_register_operand" ""))]
700 "TARGET_NEON && reload_completed"
701 [(set (match_dup 0) (match_dup 1))
702 (set (match_dup 2) (match_dup 3))
703 (set (match_dup 4) (match_dup 5))
704 (set (match_dup 6) (match_dup 7))]
706 int rdest = REGNO (operands[0]);
707 int rsrc = REGNO (operands[1]);
710 dest[0] = gen_rtx_REG (TImode, rdest);
711 src[0] = gen_rtx_REG (TImode, rsrc);
712 dest[1] = gen_rtx_REG (TImode, rdest + 4);
713 src[1] = gen_rtx_REG (TImode, rsrc + 4);
714 dest[2] = gen_rtx_REG (TImode, rdest + 8);
715 src[2] = gen_rtx_REG (TImode, rsrc + 8);
716 dest[3] = gen_rtx_REG (TImode, rdest + 12);
717 src[3] = gen_rtx_REG (TImode, rsrc + 12);
719 neon_disambiguate_copy (operands, dest, src, 4);
722 (define_insn "vec_set<mode>"
723 [(set (match_operand:VD 0 "s_register_operand" "+w")
725 (match_operand:VD 3 "s_register_operand" "0")
727 (match_operand:<V_elem> 1 "s_register_operand" "r"))
728 (ashift:SI (const_int 1)
729 (match_operand:SI 2 "immediate_operand" "i"))))]
731 "vmov%?.<V_uf_sclr>\t%P0[%c2], %1"
732 [(set_attr "predicable" "yes")
733 (set_attr "neon_type" "neon_mcr")]
736 (define_insn "vec_set<mode>"
737 [(set (match_operand:VQ 0 "s_register_operand" "+w")
739 (match_operand:VQ 3 "s_register_operand" "0")
741 (match_operand:<V_elem> 1 "s_register_operand" "r"))
742 (ashift:SI (const_int 1)
743 (match_operand:SI 2 "immediate_operand" "i"))))]
746 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
747 int elt = INTVAL (operands[2]) % half_elts;
748 int hi = (INTVAL (operands[2]) / half_elts) * 2;
749 int regno = REGNO (operands[0]);
751 operands[0] = gen_rtx_REG (<V_HALF>mode, regno + hi);
752 operands[2] = GEN_INT (elt);
754 return "vmov%?.<V_uf_sclr>\t%P0[%c2], %1";
756 [(set_attr "predicable" "yes")
757 (set_attr "neon_type" "neon_mcr")]
760 (define_insn "vec_setv2di"
761 [(set (match_operand:V2DI 0 "s_register_operand" "+w")
763 (match_operand:V2DI 3 "s_register_operand" "0")
765 (match_operand:DI 1 "s_register_operand" "r"))
766 (ashift:SI (const_int 1)
767 (match_operand:SI 2 "immediate_operand" "i"))))]
770 int regno = REGNO (operands[0]) + INTVAL (operands[2]);
772 operands[0] = gen_rtx_REG (DImode, regno);
774 return "vmov%?.64\t%P0, %Q1, %R1";
776 [(set_attr "predicable" "yes")
777 (set_attr "neon_type" "neon_mcr_2_mcrr")]
780 (define_insn "vec_extract<mode>"
781 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
783 (match_operand:VD 1 "s_register_operand" "w")
784 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
786 "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]"
787 [(set_attr "predicable" "yes")
788 (set_attr "neon_type" "neon_bp_simple")]
791 (define_insn "vec_extract<mode>"
792 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
794 (match_operand:VQ 1 "s_register_operand" "w")
795 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
798 int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
799 int elt = INTVAL (operands[2]) % half_elts;
800 int hi = (INTVAL (operands[2]) / half_elts) * 2;
801 int regno = REGNO (operands[1]);
803 operands[1] = gen_rtx_REG (<V_HALF>mode, regno + hi);
804 operands[2] = GEN_INT (elt);
806 return "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]";
808 [(set_attr "predicable" "yes")
809 (set_attr "neon_type" "neon_bp_simple")]
812 (define_insn "vec_extractv2di"
813 [(set (match_operand:DI 0 "s_register_operand" "=r")
815 (match_operand:V2DI 1 "s_register_operand" "w")
816 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
819 int regno = REGNO (operands[1]) + INTVAL (operands[2]);
821 operands[1] = gen_rtx_REG (DImode, regno);
823 return "vmov%?.64\t%Q0, %R0, %P1";
825 [(set_attr "predicable" "yes")
826 (set_attr "neon_type" "neon_int_1")]
829 (define_expand "vec_init<mode>"
830 [(match_operand:VDQ 0 "s_register_operand" "")
831 (match_operand 1 "" "")]
834 neon_expand_vector_init (operands[0], operands[1]);
838 ;; Doubleword and quadword arithmetic.
840 ;; NOTE: vadd/vsub and some other instructions also support 64-bit integer
841 ;; element size, which we could potentially use for "long long" operations. We
842 ;; don't want to do this at present though, because moving values from the
843 ;; vector unit to the ARM core is currently slow and 64-bit addition (etc.) is
844 ;; easy to do with ARM instructions anyway.
846 (define_insn "*add<mode>3_neon"
847 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
848 (plus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
849 (match_operand:VDQ 2 "s_register_operand" "w")))]
851 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
852 [(set (attr "neon_type")
853 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
854 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
855 (const_string "neon_fp_vadd_ddd_vabs_dd")
856 (const_string "neon_fp_vadd_qqq_vabs_qq"))
857 (const_string "neon_int_1")))]
860 (define_insn "*sub<mode>3_neon"
861 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
862 (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
863 (match_operand:VDQ 2 "s_register_operand" "w")))]
865 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
866 [(set (attr "neon_type")
867 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
868 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
869 (const_string "neon_fp_vadd_ddd_vabs_dd")
870 (const_string "neon_fp_vadd_qqq_vabs_qq"))
871 (const_string "neon_int_2")))]
874 (define_insn "*mul<mode>3_neon"
875 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
876 (mult:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
877 (match_operand:VDQ 2 "s_register_operand" "w")))]
879 "vmul.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
880 [(set (attr "neon_type")
881 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
882 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
883 (const_string "neon_fp_vadd_ddd_vabs_dd")
884 (const_string "neon_fp_vadd_qqq_vabs_qq"))
885 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
887 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
888 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
889 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
890 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
891 (const_string "neon_mul_qqq_8_16_32_ddd_32")
892 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
895 (define_insn "ior<mode>3"
896 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
897 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
898 (match_operand:VDQ 2 "neon_logic_op2" "w,Dl")))]
901 switch (which_alternative)
903 case 0: return "vorr\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
904 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
905 <MODE>mode, 0, VALID_NEON_QREG_MODE (<MODE>mode));
906 default: gcc_unreachable ();
909 [(set_attr "neon_type" "neon_int_1")]
912 (define_insn "iordi3_neon"
913 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
914 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w,0")
915 (match_operand:DI 2 "neon_logic_op2" "w,Dl")]
919 switch (which_alternative)
921 case 0: return "vorr\t%P0, %P1, %P2";
922 case 1: return neon_output_logic_immediate ("vorr", &operands[2],
923 DImode, 0, VALID_NEON_QREG_MODE (DImode));
924 default: gcc_unreachable ();
927 [(set_attr "neon_type" "neon_int_1")]
930 ;; The concrete forms of the Neon immediate-logic instructions are vbic and
931 ;; vorr. We support the pseudo-instruction vand instead, because that
932 ;; corresponds to the canonical form the middle-end expects to use for
933 ;; immediate bitwise-ANDs.
935 (define_insn "and<mode>3"
936 [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
937 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
938 (match_operand:VDQ 2 "neon_inv_logic_op2" "w,DL")))]
941 switch (which_alternative)
943 case 0: return "vand\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
944 case 1: return neon_output_logic_immediate ("vand", &operands[2],
945 <MODE>mode, 1, VALID_NEON_QREG_MODE (<MODE>mode));
946 default: gcc_unreachable ();
949 [(set_attr "neon_type" "neon_int_1")]
952 (define_insn "anddi3_neon"
953 [(set (match_operand:DI 0 "s_register_operand" "=w,w")
954 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w,0")
955 (match_operand:DI 2 "neon_inv_logic_op2" "w,DL")]
959 switch (which_alternative)
961 case 0: return "vand\t%P0, %P1, %P2";
962 case 1: return neon_output_logic_immediate ("vand", &operands[2],
963 DImode, 1, VALID_NEON_QREG_MODE (DImode));
964 default: gcc_unreachable ();
967 [(set_attr "neon_type" "neon_int_1")]
970 (define_insn "orn<mode>3_neon"
971 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
972 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
973 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
975 "vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
976 [(set_attr "neon_type" "neon_int_1")]
979 (define_insn "orndi3_neon"
980 [(set (match_operand:DI 0 "s_register_operand" "=w")
981 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
982 (match_operand:DI 2 "s_register_operand" "w")]
985 "vorn\t%P0, %P1, %P2"
986 [(set_attr "neon_type" "neon_int_1")]
989 (define_insn "bic<mode>3_neon"
990 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
991 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
992 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
994 "vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
995 [(set_attr "neon_type" "neon_int_1")]
998 (define_insn "bicdi3_neon"
999 [(set (match_operand:DI 0 "s_register_operand" "=w")
1000 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
1001 (match_operand:DI 2 "s_register_operand" "w")]
1004 "vbic\t%P0, %P1, %P2"
1005 [(set_attr "neon_type" "neon_int_1")]
1008 (define_insn "xor<mode>3"
1009 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1010 (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
1011 (match_operand:VDQ 2 "s_register_operand" "w")))]
1013 "veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1014 [(set_attr "neon_type" "neon_int_1")]
1017 (define_insn "xordi3_neon"
1018 [(set (match_operand:DI 0 "s_register_operand" "=w")
1019 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
1020 (match_operand:DI 2 "s_register_operand" "w")]
1023 "veor\t%P0, %P1, %P2"
1024 [(set_attr "neon_type" "neon_int_1")]
1027 (define_insn "one_cmpl<mode>2"
1028 [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1029 (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
1031 "vmvn\t%<V_reg>0, %<V_reg>1"
1032 [(set_attr "neon_type" "neon_int_1")]
1035 (define_insn "abs<mode>2"
1036 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1037 (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
1039 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
1040 [(set (attr "neon_type")
1041 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1042 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1043 (const_string "neon_fp_vadd_ddd_vabs_dd")
1044 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1045 (const_string "neon_int_3")))]
1048 (define_insn "neg<mode>2"
1049 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1050 (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
1052 "vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
1053 [(set (attr "neon_type")
1054 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1055 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1056 (const_string "neon_fp_vadd_ddd_vabs_dd")
1057 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1058 (const_string "neon_int_3")))]
1061 (define_insn "*umin<mode>3_neon"
1062 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1063 (umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1064 (match_operand:VDQIW 2 "s_register_operand" "w")))]
1066 "vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1067 [(set_attr "neon_type" "neon_int_5")]
1070 (define_insn "*umax<mode>3_neon"
1071 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1072 (umax:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1073 (match_operand:VDQIW 2 "s_register_operand" "w")))]
1075 "vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1076 [(set_attr "neon_type" "neon_int_5")]
1079 (define_insn "*smin<mode>3_neon"
1080 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1081 (smin:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
1082 (match_operand:VDQW 2 "s_register_operand" "w")))]
1084 "vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1085 [(set (attr "neon_type")
1086 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1087 (const_string "neon_fp_vadd_ddd_vabs_dd")
1088 (const_string "neon_int_5")))]
1091 (define_insn "*smax<mode>3_neon"
1092 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1093 (smax:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
1094 (match_operand:VDQW 2 "s_register_operand" "w")))]
1096 "vmax.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1097 [(set (attr "neon_type")
1098 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1099 (const_string "neon_fp_vadd_ddd_vabs_dd")
1100 (const_string "neon_int_5")))]
1103 ; TODO: V2DI shifts are current disabled because there are bugs in the
1104 ; generic vectorizer code. It ends up creating a V2DI constructor with
1107 (define_insn "ashl<mode>3"
1108 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1109 (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1110 (match_operand:VDQIW 2 "s_register_operand" "w")))]
1112 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1113 [(set (attr "neon_type")
1114 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1115 (const_string "neon_vshl_ddd")
1116 (const_string "neon_shift_3")))]
1119 ; Used for implementing logical shift-right, which is a left-shift by a negative
1120 ; amount, with signed operands. This is essentially the same as ashl<mode>3
1121 ; above, but using an unspec in case GCC tries anything tricky with negative
1124 (define_insn "ashl<mode>3_signed"
1125 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
1126 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
1127 (match_operand:VDQI 2 "s_register_operand" "w")]
1128 UNSPEC_ASHIFT_SIGNED))]
1130 "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1131 [(set (attr "neon_type")
1132 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1133 (const_string "neon_vshl_ddd")
1134 (const_string "neon_shift_3")))]
1137 ; Used for implementing logical shift-right, which is a left-shift by a negative
1138 ; amount, with unsigned operands.
1140 (define_insn "ashl<mode>3_unsigned"
1141 [(set (match_operand:VDQI 0 "s_register_operand" "=w")
1142 (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
1143 (match_operand:VDQI 2 "s_register_operand" "w")]
1144 UNSPEC_ASHIFT_UNSIGNED))]
1146 "vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1147 [(set (attr "neon_type")
1148 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1149 (const_string "neon_vshl_ddd")
1150 (const_string "neon_shift_3")))]
1153 (define_expand "ashr<mode>3"
1154 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1155 (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1156 (match_operand:VDQIW 2 "s_register_operand" "")))]
1159 rtx neg = gen_reg_rtx (<MODE>mode);
1161 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1162 emit_insn (gen_ashl<mode>3_signed (operands[0], operands[1], neg));
1167 (define_expand "lshr<mode>3"
1168 [(set (match_operand:VDQIW 0 "s_register_operand" "")
1169 (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1170 (match_operand:VDQIW 2 "s_register_operand" "")))]
1173 rtx neg = gen_reg_rtx (<MODE>mode);
1175 emit_insn (gen_neg<mode>2 (neg, operands[2]));
1176 emit_insn (gen_ashl<mode>3_unsigned (operands[0], operands[1], neg));
1181 ;; Widening operations
1183 (define_insn "widen_ssum<mode>3"
1184 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1185 (plus:<V_widen> (sign_extend:<V_widen>
1186 (match_operand:VW 1 "s_register_operand" "%w"))
1187 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1189 "vaddw.<V_s_elem>\t%q0, %q2, %P1"
1190 [(set_attr "neon_type" "neon_int_3")]
1193 (define_insn "widen_usum<mode>3"
1194 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1195 (plus:<V_widen> (zero_extend:<V_widen>
1196 (match_operand:VW 1 "s_register_operand" "%w"))
1197 (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1199 "vaddw.<V_u_elem>\t%q0, %q2, %P1"
1200 [(set_attr "neon_type" "neon_int_3")]
1203 ;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
1204 ;; shift-count granularity. That's good enough for the middle-end's current
1207 (define_expand "vec_shr_<mode>"
1208 [(match_operand:VDQ 0 "s_register_operand" "")
1209 (match_operand:VDQ 1 "s_register_operand" "")
1210 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1214 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1215 const int width = GET_MODE_BITSIZE (<MODE>mode);
1216 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1217 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1218 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1220 if (num_bits == width)
1222 emit_move_insn (operands[0], operands[1]);
1226 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1227 operands[0] = gen_lowpart (bvecmode, operands[0]);
1228 operands[1] = gen_lowpart (bvecmode, operands[1]);
1230 emit_insn (gen_ext (operands[0], operands[1], zero_reg,
1231 GEN_INT (num_bits / BITS_PER_UNIT)));
1235 (define_expand "vec_shl_<mode>"
1236 [(match_operand:VDQ 0 "s_register_operand" "")
1237 (match_operand:VDQ 1 "s_register_operand" "")
1238 (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1242 HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1243 const int width = GET_MODE_BITSIZE (<MODE>mode);
1244 const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1245 rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1246 (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1250 emit_move_insn (operands[0], CONST0_RTX (<MODE>mode));
1254 num_bits = width - num_bits;
1256 zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1257 operands[0] = gen_lowpart (bvecmode, operands[0]);
1258 operands[1] = gen_lowpart (bvecmode, operands[1]);
1260 emit_insn (gen_ext (operands[0], zero_reg, operands[1],
1261 GEN_INT (num_bits / BITS_PER_UNIT)));
1265 ;; Helpers for quad-word reduction operations
1267 ; Add (or smin, smax...) the low N/2 elements of the N-element vector
1268 ; operand[1] to the high N/2 elements of same. Put the result in operand[0], an
1269 ; N/2-element vector.
1271 (define_insn "quad_halves_<code>v4si"
1272 [(set (match_operand:V2SI 0 "s_register_operand" "=w")
1274 (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
1275 (parallel [(const_int 0) (const_int 1)]))
1276 (vec_select:V2SI (match_dup 1)
1277 (parallel [(const_int 2) (const_int 3)]))))]
1279 "<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1"
1280 [(set_attr "vqh_mnem" "<VQH_mnem>")
1281 (set (attr "neon_type")
1282 (if_then_else (eq_attr "vqh_mnem" "vadd")
1283 (const_string "neon_int_1") (const_string "neon_int_5")))]
1286 (define_insn "quad_halves_<code>v4sf"
1287 [(set (match_operand:V2SF 0 "s_register_operand" "=w")
1289 (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
1290 (parallel [(const_int 0) (const_int 1)]))
1291 (vec_select:V2SF (match_dup 1)
1292 (parallel [(const_int 2) (const_int 3)]))))]
1294 "<VQH_mnem>.f32\t%P0, %e1, %f1"
1295 [(set_attr "vqh_mnem" "<VQH_mnem>")
1296 (set (attr "neon_type")
1297 (if_then_else (eq_attr "vqh_mnem" "vadd")
1298 (const_string "neon_int_1") (const_string "neon_int_5")))]
1301 (define_insn "quad_halves_<code>v8hi"
1302 [(set (match_operand:V4HI 0 "s_register_operand" "+w")
1304 (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
1305 (parallel [(const_int 0) (const_int 1)
1306 (const_int 2) (const_int 3)]))
1307 (vec_select:V4HI (match_dup 1)
1308 (parallel [(const_int 4) (const_int 5)
1309 (const_int 6) (const_int 7)]))))]
1311 "<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1"
1312 [(set_attr "vqh_mnem" "<VQH_mnem>")
1313 (set (attr "neon_type")
1314 (if_then_else (eq_attr "vqh_mnem" "vadd")
1315 (const_string "neon_int_1") (const_string "neon_int_5")))]
1318 (define_insn "quad_halves_<code>v16qi"
1319 [(set (match_operand:V8QI 0 "s_register_operand" "+w")
1321 (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
1322 (parallel [(const_int 0) (const_int 1)
1323 (const_int 2) (const_int 3)
1324 (const_int 4) (const_int 5)
1325 (const_int 6) (const_int 7)]))
1326 (vec_select:V8QI (match_dup 1)
1327 (parallel [(const_int 8) (const_int 9)
1328 (const_int 10) (const_int 11)
1329 (const_int 12) (const_int 13)
1330 (const_int 14) (const_int 15)]))))]
1332 "<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1"
1333 [(set_attr "vqh_mnem" "<VQH_mnem>")
1334 (set (attr "neon_type")
1335 (if_then_else (eq_attr "vqh_mnem" "vadd")
1336 (const_string "neon_int_1") (const_string "neon_int_5")))]
1339 ; FIXME: We wouldn't need the following insns if we could write subregs of
1340 ; vector registers. Make an attempt at removing unnecessary moves, though
1341 ; we're really at the mercy of the register allocator.
1343 (define_insn "move_lo_quad_v4si"
1344 [(set (match_operand:V4SI 0 "s_register_operand" "+w")
1346 (match_operand:V2SI 1 "s_register_operand" "w")
1347 (vec_select:V2SI (match_dup 0)
1348 (parallel [(const_int 2) (const_int 3)]))))]
1351 int dest = REGNO (operands[0]);
1352 int src = REGNO (operands[1]);
1355 return "vmov\t%e0, %P1";
1359 [(set_attr "neon_type" "neon_bp_simple")]
1362 (define_insn "move_lo_quad_v4sf"
1363 [(set (match_operand:V4SF 0 "s_register_operand" "+w")
1365 (match_operand:V2SF 1 "s_register_operand" "w")
1366 (vec_select:V2SF (match_dup 0)
1367 (parallel [(const_int 2) (const_int 3)]))))]
1370 int dest = REGNO (operands[0]);
1371 int src = REGNO (operands[1]);
1374 return "vmov\t%e0, %P1";
1378 [(set_attr "neon_type" "neon_bp_simple")]
1381 (define_insn "move_lo_quad_v8hi"
1382 [(set (match_operand:V8HI 0 "s_register_operand" "+w")
1384 (match_operand:V4HI 1 "s_register_operand" "w")
1385 (vec_select:V4HI (match_dup 0)
1386 (parallel [(const_int 4) (const_int 5)
1387 (const_int 6) (const_int 7)]))))]
1390 int dest = REGNO (operands[0]);
1391 int src = REGNO (operands[1]);
1394 return "vmov\t%e0, %P1";
1398 [(set_attr "neon_type" "neon_bp_simple")]
1401 (define_insn "move_lo_quad_v16qi"
1402 [(set (match_operand:V16QI 0 "s_register_operand" "+w")
1404 (match_operand:V8QI 1 "s_register_operand" "w")
1405 (vec_select:V8QI (match_dup 0)
1406 (parallel [(const_int 8) (const_int 9)
1407 (const_int 10) (const_int 11)
1408 (const_int 12) (const_int 13)
1409 (const_int 14) (const_int 15)]))))]
1412 int dest = REGNO (operands[0]);
1413 int src = REGNO (operands[1]);
1416 return "vmov\t%e0, %P1";
1420 [(set_attr "neon_type" "neon_bp_simple")]
1423 ;; Reduction operations
1425 (define_expand "reduc_splus_<mode>"
1426 [(match_operand:VD 0 "s_register_operand" "")
1427 (match_operand:VD 1 "s_register_operand" "")]
1430 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1431 &gen_neon_vpadd_internal<mode>);
1435 (define_expand "reduc_splus_<mode>"
1436 [(match_operand:VQ 0 "s_register_operand" "")
1437 (match_operand:VQ 1 "s_register_operand" "")]
1440 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1441 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1443 emit_insn (gen_quad_halves_plus<mode> (step1, operands[1]));
1444 emit_insn (gen_reduc_splus_<V_half> (res_d, step1));
1445 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1450 (define_insn "reduc_splus_v2di"
1451 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1452 (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")]
1455 "vadd.i64\t%e0, %e1, %f1"
1456 [(set_attr "neon_type" "neon_int_1")]
1459 ;; NEON does not distinguish between signed and unsigned addition except on
1460 ;; widening operations.
1461 (define_expand "reduc_uplus_<mode>"
1462 [(match_operand:VDQI 0 "s_register_operand" "")
1463 (match_operand:VDQI 1 "s_register_operand" "")]
1466 emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1]));
1470 (define_expand "reduc_smin_<mode>"
1471 [(match_operand:VD 0 "s_register_operand" "")
1472 (match_operand:VD 1 "s_register_operand" "")]
1475 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1476 &gen_neon_vpsmin<mode>);
1480 (define_expand "reduc_smin_<mode>"
1481 [(match_operand:VQ 0 "s_register_operand" "")
1482 (match_operand:VQ 1 "s_register_operand" "")]
1485 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1486 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1488 emit_insn (gen_quad_halves_smin<mode> (step1, operands[1]));
1489 emit_insn (gen_reduc_smin_<V_half> (res_d, step1));
1490 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1495 (define_expand "reduc_smax_<mode>"
1496 [(match_operand:VD 0 "s_register_operand" "")
1497 (match_operand:VD 1 "s_register_operand" "")]
1500 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1501 &gen_neon_vpsmax<mode>);
1505 (define_expand "reduc_smax_<mode>"
1506 [(match_operand:VQ 0 "s_register_operand" "")
1507 (match_operand:VQ 1 "s_register_operand" "")]
1510 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1511 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1513 emit_insn (gen_quad_halves_smax<mode> (step1, operands[1]));
1514 emit_insn (gen_reduc_smax_<V_half> (res_d, step1));
1515 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1520 (define_expand "reduc_umin_<mode>"
1521 [(match_operand:VDI 0 "s_register_operand" "")
1522 (match_operand:VDI 1 "s_register_operand" "")]
1525 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1526 &gen_neon_vpumin<mode>);
1530 (define_expand "reduc_umin_<mode>"
1531 [(match_operand:VQI 0 "s_register_operand" "")
1532 (match_operand:VQI 1 "s_register_operand" "")]
1535 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1536 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1538 emit_insn (gen_quad_halves_umin<mode> (step1, operands[1]));
1539 emit_insn (gen_reduc_umin_<V_half> (res_d, step1));
1540 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1545 (define_expand "reduc_umax_<mode>"
1546 [(match_operand:VDI 0 "s_register_operand" "")
1547 (match_operand:VDI 1 "s_register_operand" "")]
1550 neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1551 &gen_neon_vpumax<mode>);
1555 (define_expand "reduc_umax_<mode>"
1556 [(match_operand:VQI 0 "s_register_operand" "")
1557 (match_operand:VQI 1 "s_register_operand" "")]
1560 rtx step1 = gen_reg_rtx (<V_HALF>mode);
1561 rtx res_d = gen_reg_rtx (<V_HALF>mode);
1563 emit_insn (gen_quad_halves_umax<mode> (step1, operands[1]));
1564 emit_insn (gen_reduc_umax_<V_half> (res_d, step1));
1565 emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1570 (define_insn "neon_vpadd_internal<mode>"
1571 [(set (match_operand:VD 0 "s_register_operand" "=w")
1572 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1573 (match_operand:VD 2 "s_register_operand" "w")]
1576 "vpadd.<V_if_elem>\t%P0, %P1, %P2"
1577 ;; Assume this schedules like vadd.
1578 [(set (attr "neon_type")
1579 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1580 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1581 (const_string "neon_fp_vadd_ddd_vabs_dd")
1582 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1583 (const_string "neon_int_1")))]
1586 (define_insn "neon_vpsmin<mode>"
1587 [(set (match_operand:VD 0 "s_register_operand" "=w")
1588 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1589 (match_operand:VD 2 "s_register_operand" "w")]
1592 "vpmin.<V_s_elem>\t%P0, %P1, %P2"
1593 ;; Assume this schedules like vmin.
1594 [(set (attr "neon_type")
1595 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1596 (const_string "neon_fp_vadd_ddd_vabs_dd")
1597 (const_string "neon_int_5")))]
1600 (define_insn "neon_vpsmax<mode>"
1601 [(set (match_operand:VD 0 "s_register_operand" "=w")
1602 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1603 (match_operand:VD 2 "s_register_operand" "w")]
1606 "vpmax.<V_s_elem>\t%P0, %P1, %P2"
1607 ;; Assume this schedules like vmax.
1608 [(set (attr "neon_type")
1609 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1610 (const_string "neon_fp_vadd_ddd_vabs_dd")
1611 (const_string "neon_int_5")))]
1614 (define_insn "neon_vpumin<mode>"
1615 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1616 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1617 (match_operand:VDI 2 "s_register_operand" "w")]
1620 "vpmin.<V_u_elem>\t%P0, %P1, %P2"
1621 ;; Assume this schedules like umin.
1622 [(set_attr "neon_type" "neon_int_5")]
1625 (define_insn "neon_vpumax<mode>"
1626 [(set (match_operand:VDI 0 "s_register_operand" "=w")
1627 (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1628 (match_operand:VDI 2 "s_register_operand" "w")]
1631 "vpmax.<V_u_elem>\t%P0, %P1, %P2"
1632 ;; Assume this schedules like umax.
1633 [(set_attr "neon_type" "neon_int_5")]
1636 ;; Saturating arithmetic
1638 ; NOTE: Neon supports many more saturating variants of instructions than the
1639 ; following, but these are all GCC currently understands.
1640 ; FIXME: Actually, GCC doesn't know how to create saturating add/sub by itself
1641 ; yet either, although these patterns may be used by intrinsics when they're
1644 (define_insn "*ss_add<mode>_neon"
1645 [(set (match_operand:VD 0 "s_register_operand" "=w")
1646 (ss_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1647 (match_operand:VD 2 "s_register_operand" "w")))]
1649 "vqadd.<V_s_elem>\t%P0, %P1, %P2"
1650 [(set_attr "neon_type" "neon_int_4")]
1653 (define_insn "*us_add<mode>_neon"
1654 [(set (match_operand:VD 0 "s_register_operand" "=w")
1655 (us_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1656 (match_operand:VD 2 "s_register_operand" "w")))]
1658 "vqadd.<V_u_elem>\t%P0, %P1, %P2"
1659 [(set_attr "neon_type" "neon_int_4")]
1662 (define_insn "*ss_sub<mode>_neon"
1663 [(set (match_operand:VD 0 "s_register_operand" "=w")
1664 (ss_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1665 (match_operand:VD 2 "s_register_operand" "w")))]
1667 "vqsub.<V_s_elem>\t%P0, %P1, %P2"
1668 [(set_attr "neon_type" "neon_int_5")]
1671 (define_insn "*us_sub<mode>_neon"
1672 [(set (match_operand:VD 0 "s_register_operand" "=w")
1673 (us_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1674 (match_operand:VD 2 "s_register_operand" "w")))]
1676 "vqsub.<V_u_elem>\t%P0, %P1, %P2"
1677 [(set_attr "neon_type" "neon_int_5")]
1680 ;; Patterns for builtins.
1682 ; good for plain vadd, vaddq.
1684 (define_insn "neon_vadd<mode>"
1685 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1686 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1687 (match_operand:VDQX 2 "s_register_operand" "w")
1688 (match_operand:SI 3 "immediate_operand" "i")]
1691 "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1692 [(set (attr "neon_type")
1693 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1694 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1695 (const_string "neon_fp_vadd_ddd_vabs_dd")
1696 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1697 (const_string "neon_int_1")))]
1700 ; operand 3 represents in bits:
1701 ; bit 0: signed (vs unsigned).
1702 ; bit 1: rounding (vs none).
1704 (define_insn "neon_vaddl<mode>"
1705 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1706 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1707 (match_operand:VDI 2 "s_register_operand" "w")
1708 (match_operand:SI 3 "immediate_operand" "i")]
1711 "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1712 [(set_attr "neon_type" "neon_int_3")]
1715 (define_insn "neon_vaddw<mode>"
1716 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1717 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1718 (match_operand:VDI 2 "s_register_operand" "w")
1719 (match_operand:SI 3 "immediate_operand" "i")]
1722 "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
1723 [(set_attr "neon_type" "neon_int_2")]
1728 (define_insn "neon_vhadd<mode>"
1729 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1730 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1731 (match_operand:VDQIW 2 "s_register_operand" "w")
1732 (match_operand:SI 3 "immediate_operand" "i")]
1735 "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1736 [(set_attr "neon_type" "neon_int_4")]
1739 (define_insn "neon_vqadd<mode>"
1740 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1741 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1742 (match_operand:VDQIX 2 "s_register_operand" "w")
1743 (match_operand:SI 3 "immediate_operand" "i")]
1746 "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1747 [(set_attr "neon_type" "neon_int_4")]
1750 (define_insn "neon_vaddhn<mode>"
1751 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
1752 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
1753 (match_operand:VN 2 "s_register_operand" "w")
1754 (match_operand:SI 3 "immediate_operand" "i")]
1757 "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2"
1758 [(set_attr "neon_type" "neon_int_4")]
1761 (define_insn "neon_vmul<mode>"
1762 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1763 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1764 (match_operand:VDQW 2 "s_register_operand" "w")
1765 (match_operand:SI 3 "immediate_operand" "i")]
1768 "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1769 [(set (attr "neon_type")
1770 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1771 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1772 (const_string "neon_fp_vadd_ddd_vabs_dd")
1773 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1774 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1776 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1777 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1778 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1779 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1780 (const_string "neon_mul_qqq_8_16_32_ddd_32")
1781 (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
1784 (define_insn "neon_vmla<mode>"
1785 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1786 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
1787 (match_operand:VDQW 2 "s_register_operand" "w")
1788 (match_operand:VDQW 3 "s_register_operand" "w")
1789 (match_operand:SI 4 "immediate_operand" "i")]
1792 "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
1793 [(set (attr "neon_type")
1794 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1795 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1796 (const_string "neon_fp_vmla_ddd")
1797 (const_string "neon_fp_vmla_qqq"))
1798 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1800 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1801 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1802 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1803 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1804 (const_string "neon_mla_qqq_8_16")
1805 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1808 (define_insn "neon_vmlal<mode>"
1809 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1810 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1811 (match_operand:VW 2 "s_register_operand" "w")
1812 (match_operand:VW 3 "s_register_operand" "w")
1813 (match_operand:SI 4 "immediate_operand" "i")]
1816 "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
1817 [(set (attr "neon_type")
1818 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1819 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1820 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1823 (define_insn "neon_vmls<mode>"
1824 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1825 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
1826 (match_operand:VDQW 2 "s_register_operand" "w")
1827 (match_operand:VDQW 3 "s_register_operand" "w")
1828 (match_operand:SI 4 "immediate_operand" "i")]
1831 "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
1832 [(set (attr "neon_type")
1833 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1834 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1835 (const_string "neon_fp_vmla_ddd")
1836 (const_string "neon_fp_vmla_qqq"))
1837 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1839 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1840 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1841 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1843 (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1844 (const_string "neon_mla_qqq_8_16")
1845 (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1848 (define_insn "neon_vmlsl<mode>"
1849 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1850 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1851 (match_operand:VW 2 "s_register_operand" "w")
1852 (match_operand:VW 3 "s_register_operand" "w")
1853 (match_operand:SI 4 "immediate_operand" "i")]
1856 "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
1857 [(set (attr "neon_type")
1858 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1859 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1860 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1863 (define_insn "neon_vqdmulh<mode>"
1864 [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
1865 (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
1866 (match_operand:VMDQI 2 "s_register_operand" "w")
1867 (match_operand:SI 3 "immediate_operand" "i")]
1870 "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1871 [(set (attr "neon_type")
1872 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1873 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1874 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1875 (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1876 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1877 (const_string "neon_mul_qqq_8_16_32_ddd_32")
1878 (const_string "neon_mul_qqq_8_16_32_ddd_32"))))]
1881 (define_insn "neon_vqdmlal<mode>"
1882 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1883 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1884 (match_operand:VMDI 2 "s_register_operand" "w")
1885 (match_operand:VMDI 3 "s_register_operand" "w")
1886 (match_operand:SI 4 "immediate_operand" "i")]
1889 "vqdmlal.<V_s_elem>\t%q0, %P2, %P3"
1890 [(set (attr "neon_type")
1891 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1892 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1893 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1896 (define_insn "neon_vqdmlsl<mode>"
1897 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1898 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1899 (match_operand:VMDI 2 "s_register_operand" "w")
1900 (match_operand:VMDI 3 "s_register_operand" "w")
1901 (match_operand:SI 4 "immediate_operand" "i")]
1904 "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3"
1905 [(set (attr "neon_type")
1906 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1907 (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1908 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1911 (define_insn "neon_vmull<mode>"
1912 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1913 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
1914 (match_operand:VW 2 "s_register_operand" "w")
1915 (match_operand:SI 3 "immediate_operand" "i")]
1918 "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1919 [(set (attr "neon_type")
1920 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1921 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1922 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1925 (define_insn "neon_vqdmull<mode>"
1926 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1927 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
1928 (match_operand:VMDI 2 "s_register_operand" "w")
1929 (match_operand:SI 3 "immediate_operand" "i")]
1932 "vqdmull.<V_s_elem>\t%q0, %P1, %P2"
1933 [(set (attr "neon_type")
1934 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
1935 (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1936 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1939 (define_insn "neon_vsub<mode>"
1940 [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1941 (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1942 (match_operand:VDQX 2 "s_register_operand" "w")
1943 (match_operand:SI 3 "immediate_operand" "i")]
1946 "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1947 [(set (attr "neon_type")
1948 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
1949 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
1950 (const_string "neon_fp_vadd_ddd_vabs_dd")
1951 (const_string "neon_fp_vadd_qqq_vabs_qq"))
1952 (const_string "neon_int_2")))]
1955 (define_insn "neon_vsubl<mode>"
1956 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1957 (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1958 (match_operand:VDI 2 "s_register_operand" "w")
1959 (match_operand:SI 3 "immediate_operand" "i")]
1962 "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1963 [(set_attr "neon_type" "neon_int_2")]
1966 (define_insn "neon_vsubw<mode>"
1967 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1968 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1969 (match_operand:VDI 2 "s_register_operand" "w")
1970 (match_operand:SI 3 "immediate_operand" "i")]
1973 "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
1974 [(set_attr "neon_type" "neon_int_2")]
1977 (define_insn "neon_vqsub<mode>"
1978 [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1979 (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1980 (match_operand:VDQIX 2 "s_register_operand" "w")
1981 (match_operand:SI 3 "immediate_operand" "i")]
1984 "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1985 [(set_attr "neon_type" "neon_int_5")]
1988 (define_insn "neon_vhsub<mode>"
1989 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1990 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1991 (match_operand:VDQIW 2 "s_register_operand" "w")
1992 (match_operand:SI 3 "immediate_operand" "i")]
1995 "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1996 [(set_attr "neon_type" "neon_int_5")]
1999 (define_insn "neon_vsubhn<mode>"
2000 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2001 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2002 (match_operand:VN 2 "s_register_operand" "w")
2003 (match_operand:SI 3 "immediate_operand" "i")]
2006 "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2"
2007 [(set_attr "neon_type" "neon_int_4")]
2010 (define_insn "neon_vceq<mode>"
2011 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2012 (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
2013 (match_operand:VDQW 2 "s_register_operand" "w")
2014 (match_operand:SI 3 "immediate_operand" "i")]
2017 "vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2018 [(set (attr "neon_type")
2019 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2020 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2021 (const_string "neon_fp_vadd_ddd_vabs_dd")
2022 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2023 (const_string "neon_int_5")))]
2026 (define_insn "neon_vcge<mode>"
2027 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2028 (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
2029 (match_operand:VDQW 2 "s_register_operand" "w")
2030 (match_operand:SI 3 "immediate_operand" "i")]
2033 "vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2034 [(set (attr "neon_type")
2035 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2036 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2037 (const_string "neon_fp_vadd_ddd_vabs_dd")
2038 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2039 (const_string "neon_int_5")))]
2042 (define_insn "neon_vcgt<mode>"
2043 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2044 (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
2045 (match_operand:VDQW 2 "s_register_operand" "w")
2046 (match_operand:SI 3 "immediate_operand" "i")]
2049 "vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2050 [(set (attr "neon_type")
2051 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2052 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2053 (const_string "neon_fp_vadd_ddd_vabs_dd")
2054 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2055 (const_string "neon_int_5")))]
2058 (define_insn "neon_vcage<mode>"
2059 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2060 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2061 (match_operand:VCVTF 2 "s_register_operand" "w")
2062 (match_operand:SI 3 "immediate_operand" "i")]
2065 "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2066 [(set (attr "neon_type")
2067 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2068 (const_string "neon_fp_vadd_ddd_vabs_dd")
2069 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2072 (define_insn "neon_vcagt<mode>"
2073 [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2074 (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2075 (match_operand:VCVTF 2 "s_register_operand" "w")
2076 (match_operand:SI 3 "immediate_operand" "i")]
2079 "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2080 [(set (attr "neon_type")
2081 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2082 (const_string "neon_fp_vadd_ddd_vabs_dd")
2083 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2086 (define_insn "neon_vtst<mode>"
2087 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2088 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2089 (match_operand:VDQIW 2 "s_register_operand" "w")
2090 (match_operand:SI 3 "immediate_operand" "i")]
2093 "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2094 [(set_attr "neon_type" "neon_int_4")]
2097 (define_insn "neon_vabd<mode>"
2098 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2099 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2100 (match_operand:VDQW 2 "s_register_operand" "w")
2101 (match_operand:SI 3 "immediate_operand" "i")]
2104 "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2105 [(set (attr "neon_type")
2106 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2107 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2108 (const_string "neon_fp_vadd_ddd_vabs_dd")
2109 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2110 (const_string "neon_int_5")))]
2113 (define_insn "neon_vabdl<mode>"
2114 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2115 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2116 (match_operand:VW 2 "s_register_operand" "w")
2117 (match_operand:SI 3 "immediate_operand" "i")]
2120 "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2121 [(set_attr "neon_type" "neon_int_5")]
2124 (define_insn "neon_vaba<mode>"
2125 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2126 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "0")
2127 (match_operand:VDQIW 2 "s_register_operand" "w")
2128 (match_operand:VDQIW 3 "s_register_operand" "w")
2129 (match_operand:SI 4 "immediate_operand" "i")]
2132 "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2133 [(set (attr "neon_type")
2134 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2135 (const_string "neon_vaba") (const_string "neon_vaba_qqq")))]
2138 (define_insn "neon_vabal<mode>"
2139 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2140 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2141 (match_operand:VW 2 "s_register_operand" "w")
2142 (match_operand:VW 3 "s_register_operand" "w")
2143 (match_operand:SI 4 "immediate_operand" "i")]
2146 "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2147 [(set_attr "neon_type" "neon_vaba")]
2150 (define_insn "neon_vmax<mode>"
2151 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2152 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2153 (match_operand:VDQW 2 "s_register_operand" "w")
2154 (match_operand:SI 3 "immediate_operand" "i")]
2157 "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2158 [(set (attr "neon_type")
2159 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2160 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2161 (const_string "neon_fp_vadd_ddd_vabs_dd")
2162 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2163 (const_string "neon_int_5")))]
2166 (define_insn "neon_vmin<mode>"
2167 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2168 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2169 (match_operand:VDQW 2 "s_register_operand" "w")
2170 (match_operand:SI 3 "immediate_operand" "i")]
2173 "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2174 [(set (attr "neon_type")
2175 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2176 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2177 (const_string "neon_fp_vadd_ddd_vabs_dd")
2178 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2179 (const_string "neon_int_5")))]
2182 (define_expand "neon_vpadd<mode>"
2183 [(match_operand:VD 0 "s_register_operand" "=w")
2184 (match_operand:VD 1 "s_register_operand" "w")
2185 (match_operand:VD 2 "s_register_operand" "w")
2186 (match_operand:SI 3 "immediate_operand" "i")]
2189 emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1],
2194 (define_insn "neon_vpaddl<mode>"
2195 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2196 (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")
2197 (match_operand:SI 2 "immediate_operand" "i")]
2200 "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2201 ;; Assume this schedules like vaddl.
2202 [(set_attr "neon_type" "neon_int_3")]
2205 (define_insn "neon_vpadal<mode>"
2206 [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2207 (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0")
2208 (match_operand:VDQIW 2 "s_register_operand" "w")
2209 (match_operand:SI 3 "immediate_operand" "i")]
2212 "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
2213 ;; Assume this schedules like vpadd.
2214 [(set_attr "neon_type" "neon_int_1")]
2217 (define_insn "neon_vpmax<mode>"
2218 [(set (match_operand:VD 0 "s_register_operand" "=w")
2219 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2220 (match_operand:VD 2 "s_register_operand" "w")
2221 (match_operand:SI 3 "immediate_operand" "i")]
2224 "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2225 ;; Assume this schedules like vmax.
2226 [(set (attr "neon_type")
2227 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2228 (const_string "neon_fp_vadd_ddd_vabs_dd")
2229 (const_string "neon_int_5")))]
2232 (define_insn "neon_vpmin<mode>"
2233 [(set (match_operand:VD 0 "s_register_operand" "=w")
2234 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2235 (match_operand:VD 2 "s_register_operand" "w")
2236 (match_operand:SI 3 "immediate_operand" "i")]
2239 "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2240 ;; Assume this schedules like vmin.
2241 [(set (attr "neon_type")
2242 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2243 (const_string "neon_fp_vadd_ddd_vabs_dd")
2244 (const_string "neon_int_5")))]
2247 (define_insn "neon_vrecps<mode>"
2248 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2249 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2250 (match_operand:VCVTF 2 "s_register_operand" "w")
2251 (match_operand:SI 3 "immediate_operand" "i")]
2254 "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2255 [(set (attr "neon_type")
2256 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2257 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2258 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2261 (define_insn "neon_vrsqrts<mode>"
2262 [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2263 (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2264 (match_operand:VCVTF 2 "s_register_operand" "w")
2265 (match_operand:SI 3 "immediate_operand" "i")]
2268 "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2269 [(set (attr "neon_type")
2270 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2271 (const_string "neon_fp_vrecps_vrsqrts_ddd")
2272 (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2275 (define_insn "neon_vabs<mode>"
2276 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2277 (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2278 (match_operand:SI 2 "immediate_operand" "i")]
2281 "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2282 [(set (attr "neon_type")
2283 (if_then_else (ior (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2284 (ne (symbol_ref "<Is_float_mode>") (const_int 0)))
2286 (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2287 (const_string "neon_fp_vadd_ddd_vabs_dd")
2288 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2289 (const_string "neon_vqneg_vqabs")))]
2292 (define_insn "neon_vqabs<mode>"
2293 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2294 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2295 (match_operand:SI 2 "immediate_operand" "i")]
2298 "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2299 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2302 (define_expand "neon_vneg<mode>"
2303 [(match_operand:VDQW 0 "s_register_operand" "")
2304 (match_operand:VDQW 1 "s_register_operand" "")
2305 (match_operand:SI 2 "immediate_operand" "")]
2308 emit_insn (gen_neg<mode>2 (operands[0], operands[1]));
2312 (define_insn "neon_vqneg<mode>"
2313 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2314 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2315 (match_operand:SI 2 "immediate_operand" "i")]
2318 "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2319 [(set_attr "neon_type" "neon_vqneg_vqabs")]
2322 (define_insn "neon_vcls<mode>"
2323 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2324 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2325 (match_operand:SI 2 "immediate_operand" "i")]
2328 "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2329 [(set_attr "neon_type" "neon_int_1")]
2332 (define_insn "neon_vclz<mode>"
2333 [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2334 (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2335 (match_operand:SI 2 "immediate_operand" "i")]
2338 "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1"
2339 [(set_attr "neon_type" "neon_int_1")]
2342 (define_insn "neon_vcnt<mode>"
2343 [(set (match_operand:VE 0 "s_register_operand" "=w")
2344 (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
2345 (match_operand:SI 2 "immediate_operand" "i")]
2348 "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2349 [(set_attr "neon_type" "neon_int_1")]
2352 (define_insn "neon_vrecpe<mode>"
2353 [(set (match_operand:V32 0 "s_register_operand" "=w")
2354 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2355 (match_operand:SI 2 "immediate_operand" "i")]
2358 "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2359 [(set (attr "neon_type")
2360 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2361 (const_string "neon_fp_vadd_ddd_vabs_dd")
2362 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2365 (define_insn "neon_vrsqrte<mode>"
2366 [(set (match_operand:V32 0 "s_register_operand" "=w")
2367 (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2368 (match_operand:SI 2 "immediate_operand" "i")]
2371 "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2372 [(set (attr "neon_type")
2373 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2374 (const_string "neon_fp_vadd_ddd_vabs_dd")
2375 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2378 (define_expand "neon_vmvn<mode>"
2379 [(match_operand:VDQIW 0 "s_register_operand" "")
2380 (match_operand:VDQIW 1 "s_register_operand" "")
2381 (match_operand:SI 2 "immediate_operand" "")]
2384 emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1]));
2388 ;; FIXME: 32-bit element sizes are a bit funky (should be output as .32 not
2389 ;; .u32), but the assembler should cope with that.
2391 (define_insn "neon_vget_lane<mode>"
2392 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
2393 (unspec:<V_elem> [(match_operand:VD 1 "s_register_operand" "w")
2394 (match_operand:SI 2 "immediate_operand" "i")
2395 (match_operand:SI 3 "immediate_operand" "i")]
2398 "vmov%?.%t3%#<V_sz_elem>\t%0, %P1[%c2]"
2399 [(set_attr "predicable" "yes")
2400 (set_attr "neon_type" "neon_bp_simple")]
2403 ; Operand 2 (lane number) is ignored because we can only extract the zeroth lane
2404 ; with this insn. Operand 3 (info word) is ignored because it does nothing
2405 ; useful with 64-bit elements.
2407 (define_insn "neon_vget_lanedi"
2408 [(set (match_operand:DI 0 "s_register_operand" "=r")
2409 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
2410 (match_operand:SI 2 "immediate_operand" "i")
2411 (match_operand:SI 3 "immediate_operand" "i")]
2414 "vmov%?\t%Q0, %R0, %P1 @ di"
2415 [(set_attr "predicable" "yes")
2416 (set_attr "neon_type" "neon_bp_simple")]
2419 (define_insn "neon_vget_lane<mode>"
2420 [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
2421 (unspec:<V_elem> [(match_operand:VQ 1 "s_register_operand" "w")
2422 (match_operand:SI 2 "immediate_operand" "i")
2423 (match_operand:SI 3 "immediate_operand" "i")]
2428 int regno = REGNO (operands[1]);
2429 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2430 unsigned int elt = INTVAL (operands[2]);
2432 ops[0] = operands[0];
2433 ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2434 ops[2] = GEN_INT (elt % halfelts);
2435 ops[3] = operands[3];
2436 output_asm_insn ("vmov%?.%t3%#<V_sz_elem>\t%0, %P1[%c2]", ops);
2440 [(set_attr "predicable" "yes")
2441 (set_attr "neon_type" "neon_bp_simple")]
2444 (define_insn "neon_vget_lanev2di"
2445 [(set (match_operand:DI 0 "s_register_operand" "=r")
2446 (unspec:DI [(match_operand:V2DI 1 "s_register_operand" "w")
2447 (match_operand:SI 2 "immediate_operand" "i")
2448 (match_operand:SI 3 "immediate_operand" "i")]
2453 unsigned int regno = REGNO (operands[1]);
2454 unsigned int elt = INTVAL (operands[2]);
2456 ops[0] = operands[0];
2457 ops[1] = gen_rtx_REG (DImode, regno + 2 * elt);
2458 output_asm_insn ("vmov%?\t%Q0, %R0, %P1 @ v2di", ops);
2462 [(set_attr "predicable" "yes")
2463 (set_attr "neon_type" "neon_bp_simple")]
2466 (define_insn "neon_vset_lane<mode>"
2467 [(set (match_operand:VD 0 "s_register_operand" "=w")
2468 (unspec:VD [(match_operand:<V_elem> 1 "s_register_operand" "r")
2469 (match_operand:VD 2 "s_register_operand" "0")
2470 (match_operand:SI 3 "immediate_operand" "i")]
2473 "vmov%?.<V_sz_elem>\t%P0[%c3], %1"
2474 [(set_attr "predicable" "yes")
2475 (set_attr "neon_type" "neon_bp_simple")]
2478 ; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
2480 (define_insn "neon_vset_lanedi"
2481 [(set (match_operand:DI 0 "s_register_operand" "=w")
2482 (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")
2483 (match_operand:DI 2 "s_register_operand" "0")
2484 (match_operand:SI 3 "immediate_operand" "i")]
2487 "vmov%?\t%P0, %Q1, %R1 @ di"
2488 [(set_attr "predicable" "yes")
2489 (set_attr "neon_type" "neon_bp_simple")]
2492 (define_insn "neon_vset_lane<mode>"
2493 [(set (match_operand:VQ 0 "s_register_operand" "=w")
2494 (unspec:VQ [(match_operand:<V_elem> 1 "s_register_operand" "r")
2495 (match_operand:VQ 2 "s_register_operand" "0")
2496 (match_operand:SI 3 "immediate_operand" "i")]
2501 unsigned int regno = REGNO (operands[0]);
2502 unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2503 unsigned int elt = INTVAL (operands[3]);
2505 ops[0] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2506 ops[1] = operands[1];
2507 ops[2] = GEN_INT (elt % halfelts);
2508 output_asm_insn ("vmov%?.<V_sz_elem>\t%P0[%c2], %1", ops);
2512 [(set_attr "predicable" "yes")
2513 (set_attr "neon_type" "neon_bp_simple")]
2516 (define_insn "neon_vset_lanev2di"
2517 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2518 (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "r")
2519 (match_operand:V2DI 2 "s_register_operand" "0")
2520 (match_operand:SI 3 "immediate_operand" "i")]
2525 unsigned int regno = REGNO (operands[0]);
2526 unsigned int elt = INTVAL (operands[3]);
2528 ops[0] = gen_rtx_REG (DImode, regno + 2 * elt);
2529 ops[1] = operands[1];
2530 output_asm_insn ("vmov%?\t%P0, %Q1, %R1 @ v2di", ops);
2534 [(set_attr "predicable" "yes")
2535 (set_attr "neon_type" "neon_bp_simple")]
2538 (define_expand "neon_vcreate<mode>"
2539 [(match_operand:VDX 0 "s_register_operand" "")
2540 (match_operand:DI 1 "general_operand" "")]
2543 rtx src = gen_lowpart (<MODE>mode, operands[1]);
2544 emit_move_insn (operands[0], src);
2548 (define_insn "neon_vdup_n<mode>"
2549 [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2550 (unspec:VDQW [(match_operand:<V_elem> 1 "s_register_operand" "r")]
2553 "vdup%?.<V_sz_elem>\t%<V_reg>0, %1"
2554 ;; Assume this schedules like vmov.
2555 [(set_attr "predicable" "yes")
2556 (set_attr "neon_type" "neon_bp_simple")]
2559 (define_insn "neon_vdup_ndi"
2560 [(set (match_operand:DI 0 "s_register_operand" "=w")
2561 (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")]
2564 "vmov%?\t%P0, %Q1, %R1"
2565 [(set_attr "predicable" "yes")
2566 (set_attr "neon_type" "neon_bp_simple")]
2569 (define_insn "neon_vdup_nv2di"
2570 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2571 (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "r")]
2574 "vmov%?\t%e0, %Q1, %R1\;vmov%?\t%f0, %Q1, %R1"
2575 [(set_attr "predicable" "yes")
2576 (set_attr "length" "8")
2577 (set_attr "neon_type" "neon_bp_simple")]
2580 (define_insn "neon_vdup_lane<mode>"
2581 [(set (match_operand:VD 0 "s_register_operand" "=w")
2582 (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2583 (match_operand:SI 2 "immediate_operand" "i")]
2586 "vdup.<V_sz_elem>\t%P0, %P1[%c2]"
2587 ;; Assume this schedules like vmov.
2588 [(set_attr "neon_type" "neon_bp_simple")]
2591 (define_insn "neon_vdup_lane<mode>"
2592 [(set (match_operand:VQ 0 "s_register_operand" "=w")
2593 (unspec:VQ [(match_operand:<V_HALF> 1 "s_register_operand" "w")
2594 (match_operand:SI 2 "immediate_operand" "i")]
2597 "vdup.<V_sz_elem>\t%q0, %P1[%c2]"
2598 ;; Assume this schedules like vmov.
2599 [(set_attr "neon_type" "neon_bp_simple")]
2602 ; Scalar index is ignored, since only zero is valid here.
2603 (define_expand "neon_vdup_lanedi"
2604 [(set (match_operand:DI 0 "s_register_operand" "=w")
2605 (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
2606 (match_operand:SI 2 "immediate_operand" "i")]
2610 emit_move_insn (operands[0], operands[1]);
2615 (define_insn "neon_vdup_lanev2di"
2616 [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2617 (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "w")
2618 (match_operand:SI 2 "immediate_operand" "i")]
2621 "vmov\t%e0, %P1\;vmov\t%f0, %P1"
2622 [(set_attr "length" "8")
2623 (set_attr "neon_type" "neon_bp_simple")]
2626 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
2628 ;; FIXME: A different implementation of this builtin could make it much
2629 ;; more likely that we wouldn't actually need to output anything (we could make
2630 ;; it so that the reg allocator puts things in the right places magically
2631 ;; instead). Lack of subregs for vectors makes that tricky though, I think.
2633 (define_insn "neon_vcombine<mode>"
2634 [(set (match_operand:<V_DOUBLE> 0 "s_register_operand" "=w")
2635 (unspec:<V_DOUBLE> [(match_operand:VDX 1 "s_register_operand" "w")
2636 (match_operand:VDX 2 "s_register_operand" "w")]
2640 int dest = REGNO (operands[0]);
2641 int src1 = REGNO (operands[1]);
2642 int src2 = REGNO (operands[2]);
2645 if (src1 == dest && src2 == dest + 2)
2647 else if (src2 == dest && src1 == dest + 2)
2648 /* Special case of reversed high/low parts. */
2649 return "vswp\t%P1, %P2";
2651 destlo = gen_rtx_REG (<MODE>mode, dest);
2653 if (!reg_overlap_mentioned_p (operands[2], destlo))
2655 /* Try to avoid unnecessary moves if part of the result is in the right
2658 output_asm_insn ("vmov\t%e0, %P1", operands);
2659 if (src2 != dest + 2)
2660 output_asm_insn ("vmov\t%f0, %P2", operands);
2664 if (src2 != dest + 2)
2665 output_asm_insn ("vmov\t%f0, %P2", operands);
2667 output_asm_insn ("vmov\t%e0, %P1", operands);
2672 ;; We set the neon_type attribute based on the vmov instructions above.
2673 [(set_attr "length" "8")
2674 (set_attr "neon_type" "neon_bp_simple")]
2677 (define_insn "neon_vget_high<mode>"
2678 [(set (match_operand:<V_HALF> 0 "s_register_operand" "=w")
2679 (unspec:<V_HALF> [(match_operand:VQX 1 "s_register_operand" "w")]
2683 int dest = REGNO (operands[0]);
2684 int src = REGNO (operands[1]);
2686 if (dest != src + 2)
2687 return "vmov\t%P0, %f1";
2691 [(set_attr "neon_type" "neon_bp_simple")]
2694 (define_insn "neon_vget_low<mode>"
2695 [(set (match_operand:<V_HALF> 0 "s_register_operand" "=w")
2696 (unspec:<V_HALF> [(match_operand:VQX 1 "s_register_operand" "w")]
2700 int dest = REGNO (operands[0]);
2701 int src = REGNO (operands[1]);
2704 return "vmov\t%P0, %e1";
2708 [(set_attr "neon_type" "neon_bp_simple")]
2711 (define_insn "neon_vcvt<mode>"
2712 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2713 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
2714 (match_operand:SI 2 "immediate_operand" "i")]
2717 "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1"
2718 [(set (attr "neon_type")
2719 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2720 (const_string "neon_fp_vadd_ddd_vabs_dd")
2721 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2724 (define_insn "neon_vcvt<mode>"
2725 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2726 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
2727 (match_operand:SI 2 "immediate_operand" "i")]
2730 "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1"
2731 [(set (attr "neon_type")
2732 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2733 (const_string "neon_fp_vadd_ddd_vabs_dd")
2734 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2737 (define_insn "neon_vcvt_n<mode>"
2738 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2739 (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
2740 (match_operand:SI 2 "immediate_operand" "i")
2741 (match_operand:SI 3 "immediate_operand" "i")]
2744 "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2"
2745 [(set (attr "neon_type")
2746 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2747 (const_string "neon_fp_vadd_ddd_vabs_dd")
2748 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2751 (define_insn "neon_vcvt_n<mode>"
2752 [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2753 (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
2754 (match_operand:SI 2 "immediate_operand" "i")
2755 (match_operand:SI 3 "immediate_operand" "i")]
2758 "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2"
2759 [(set (attr "neon_type")
2760 (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
2761 (const_string "neon_fp_vadd_ddd_vabs_dd")
2762 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2765 (define_insn "neon_vmovn<mode>"
2766 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2767 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2768 (match_operand:SI 2 "immediate_operand" "i")]
2771 "vmovn.<V_if_elem>\t%P0, %q1"
2772 [(set_attr "neon_type" "neon_bp_simple")]
2775 (define_insn "neon_vqmovn<mode>"
2776 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2777 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2778 (match_operand:SI 2 "immediate_operand" "i")]
2781 "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1"
2782 [(set_attr "neon_type" "neon_shift_2")]
2785 (define_insn "neon_vqmovun<mode>"
2786 [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2787 (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2788 (match_operand:SI 2 "immediate_operand" "i")]
2791 "vqmovun.<V_s_elem>\t%P0, %q1"
2792 [(set_attr "neon_type" "neon_shift_2")]
2795 (define_insn "neon_vmovl<mode>"
2796 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2797 (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2798 (match_operand:SI 2 "immediate_operand" "i")]
2801 "vmovl.%T2%#<V_sz_elem>\t%q0, %P1"
2802 [(set_attr "neon_type" "neon_shift_1")]
2805 (define_insn "neon_vmul_lane<mode>"
2806 [(set (match_operand:VMD 0 "s_register_operand" "=w")
2807 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
2808 (match_operand:VMD 2 "s_register_operand"
2809 "<scalar_mul_constraint>")
2810 (match_operand:SI 3 "immediate_operand" "i")
2811 (match_operand:SI 4 "immediate_operand" "i")]
2814 "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]"
2815 [(set (attr "neon_type")
2816 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2817 (const_string "neon_fp_vmul_ddd")
2818 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2819 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
2820 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))))]
2823 (define_insn "neon_vmul_lane<mode>"
2824 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
2825 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
2826 (match_operand:<V_HALF> 2 "s_register_operand"
2827 "<scalar_mul_constraint>")
2828 (match_operand:SI 3 "immediate_operand" "i")
2829 (match_operand:SI 4 "immediate_operand" "i")]
2832 "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]"
2833 [(set (attr "neon_type")
2834 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2835 (const_string "neon_fp_vmul_qqd")
2836 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2837 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
2838 (const_string "neon_mul_qqd_32_scalar"))))]
2841 (define_insn "neon_vmull_lane<mode>"
2842 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2843 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
2844 (match_operand:VMDI 2 "s_register_operand"
2845 "<scalar_mul_constraint>")
2846 (match_operand:SI 3 "immediate_operand" "i")
2847 (match_operand:SI 4 "immediate_operand" "i")]
2848 UNSPEC_VMULL_LANE))]
2850 "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]"
2851 [(set (attr "neon_type")
2852 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2853 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
2854 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2857 (define_insn "neon_vqdmull_lane<mode>"
2858 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2859 (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
2860 (match_operand:VMDI 2 "s_register_operand"
2861 "<scalar_mul_constraint>")
2862 (match_operand:SI 3 "immediate_operand" "i")
2863 (match_operand:SI 4 "immediate_operand" "i")]
2864 UNSPEC_VQDMULL_LANE))]
2866 "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]"
2867 [(set (attr "neon_type")
2868 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2869 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
2870 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2873 (define_insn "neon_vqdmulh_lane<mode>"
2874 [(set (match_operand:VMQI 0 "s_register_operand" "=w")
2875 (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
2876 (match_operand:<V_HALF> 2 "s_register_operand"
2877 "<scalar_mul_constraint>")
2878 (match_operand:SI 3 "immediate_operand" "i")
2879 (match_operand:SI 4 "immediate_operand" "i")]
2880 UNSPEC_VQDMULH_LANE))]
2882 "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]"
2883 [(set (attr "neon_type")
2884 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2885 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
2886 (const_string "neon_mul_qqd_32_scalar")))]
2889 (define_insn "neon_vqdmulh_lane<mode>"
2890 [(set (match_operand:VMDI 0 "s_register_operand" "=w")
2891 (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
2892 (match_operand:VMDI 2 "s_register_operand"
2893 "<scalar_mul_constraint>")
2894 (match_operand:SI 3 "immediate_operand" "i")
2895 (match_operand:SI 4 "immediate_operand" "i")]
2896 UNSPEC_VQDMULH_LANE))]
2898 "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]"
2899 [(set (attr "neon_type")
2900 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2901 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
2902 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2905 (define_insn "neon_vmla_lane<mode>"
2906 [(set (match_operand:VMD 0 "s_register_operand" "=w")
2907 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
2908 (match_operand:VMD 2 "s_register_operand" "w")
2909 (match_operand:VMD 3 "s_register_operand"
2910 "<scalar_mul_constraint>")
2911 (match_operand:SI 4 "immediate_operand" "i")
2912 (match_operand:SI 5 "immediate_operand" "i")]
2915 "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]"
2916 [(set (attr "neon_type")
2917 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2918 (const_string "neon_fp_vmla_ddd_scalar")
2919 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2920 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
2921 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
2924 (define_insn "neon_vmla_lane<mode>"
2925 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
2926 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
2927 (match_operand:VMQ 2 "s_register_operand" "w")
2928 (match_operand:<V_HALF> 3 "s_register_operand"
2929 "<scalar_mul_constraint>")
2930 (match_operand:SI 4 "immediate_operand" "i")
2931 (match_operand:SI 5 "immediate_operand" "i")]
2934 "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]"
2935 [(set (attr "neon_type")
2936 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2937 (const_string "neon_fp_vmla_qqq_scalar")
2938 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2939 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
2940 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
2943 (define_insn "neon_vmlal_lane<mode>"
2944 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2945 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2946 (match_operand:VMDI 2 "s_register_operand" "w")
2947 (match_operand:VMDI 3 "s_register_operand"
2948 "<scalar_mul_constraint>")
2949 (match_operand:SI 4 "immediate_operand" "i")
2950 (match_operand:SI 5 "immediate_operand" "i")]
2951 UNSPEC_VMLAL_LANE))]
2953 "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]"
2954 [(set (attr "neon_type")
2955 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2956 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
2957 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2960 (define_insn "neon_vqdmlal_lane<mode>"
2961 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2962 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2963 (match_operand:VMDI 2 "s_register_operand" "w")
2964 (match_operand:VMDI 3 "s_register_operand"
2965 "<scalar_mul_constraint>")
2966 (match_operand:SI 4 "immediate_operand" "i")
2967 (match_operand:SI 5 "immediate_operand" "i")]
2968 UNSPEC_VQDMLAL_LANE))]
2970 "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]"
2971 [(set (attr "neon_type")
2972 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2973 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
2974 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2977 (define_insn "neon_vmls_lane<mode>"
2978 [(set (match_operand:VMD 0 "s_register_operand" "=w")
2979 (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
2980 (match_operand:VMD 2 "s_register_operand" "w")
2981 (match_operand:VMD 3 "s_register_operand"
2982 "<scalar_mul_constraint>")
2983 (match_operand:SI 4 "immediate_operand" "i")
2984 (match_operand:SI 5 "immediate_operand" "i")]
2987 "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]"
2988 [(set (attr "neon_type")
2989 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
2990 (const_string "neon_fp_vmla_ddd_scalar")
2991 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
2992 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
2993 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
2996 (define_insn "neon_vmls_lane<mode>"
2997 [(set (match_operand:VMQ 0 "s_register_operand" "=w")
2998 (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
2999 (match_operand:VMQ 2 "s_register_operand" "w")
3000 (match_operand:<V_HALF> 3 "s_register_operand"
3001 "<scalar_mul_constraint>")
3002 (match_operand:SI 4 "immediate_operand" "i")
3003 (match_operand:SI 5 "immediate_operand" "i")]
3006 "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]"
3007 [(set (attr "neon_type")
3008 (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
3009 (const_string "neon_fp_vmla_qqq_scalar")
3010 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3011 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3012 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3015 (define_insn "neon_vmlsl_lane<mode>"
3016 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3017 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3018 (match_operand:VMDI 2 "s_register_operand" "w")
3019 (match_operand:VMDI 3 "s_register_operand"
3020 "<scalar_mul_constraint>")
3021 (match_operand:SI 4 "immediate_operand" "i")
3022 (match_operand:SI 5 "immediate_operand" "i")]
3023 UNSPEC_VMLSL_LANE))]
3025 "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]"
3026 [(set (attr "neon_type")
3027 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3028 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3029 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3032 (define_insn "neon_vqdmlsl_lane<mode>"
3033 [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3034 (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3035 (match_operand:VMDI 2 "s_register_operand" "w")
3036 (match_operand:VMDI 3 "s_register_operand"
3037 "<scalar_mul_constraint>")
3038 (match_operand:SI 4 "immediate_operand" "i")
3039 (match_operand:SI 5 "immediate_operand" "i")]
3040 UNSPEC_VQDMLSL_LANE))]
3042 "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]"
3043 [(set (attr "neon_type")
3044 (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
3045 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3046 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3049 ; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
3050 ; core register into a temp register, then use a scalar taken from that. This
3051 ; isn't an optimal solution if e.g. the scalar has just been read from memory
3052 ; or extracted from another vector. The latter case it's currently better to
3053 ; use the "_lane" variant, and the former case can probably be implemented
3054 ; using vld1_lane, but that hasn't been done yet.
3056 (define_expand "neon_vmul_n<mode>"
3057 [(match_operand:VMD 0 "s_register_operand" "")
3058 (match_operand:VMD 1 "s_register_operand" "")
3059 (match_operand:<V_elem> 2 "s_register_operand" "")
3060 (match_operand:SI 3 "immediate_operand" "")]
3063 rtx tmp = gen_reg_rtx (<MODE>mode);
3064 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3065 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3066 const0_rtx, const0_rtx));
3070 (define_expand "neon_vmul_n<mode>"
3071 [(match_operand:VMQ 0 "s_register_operand" "")
3072 (match_operand:VMQ 1 "s_register_operand" "")
3073 (match_operand:<V_elem> 2 "s_register_operand" "")
3074 (match_operand:SI 3 "immediate_operand" "")]
3077 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3078 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3079 emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3080 const0_rtx, const0_rtx));
3084 (define_expand "neon_vmull_n<mode>"
3085 [(match_operand:<V_widen> 0 "s_register_operand" "")
3086 (match_operand:VMDI 1 "s_register_operand" "")
3087 (match_operand:<V_elem> 2 "s_register_operand" "")
3088 (match_operand:SI 3 "immediate_operand" "")]
3091 rtx tmp = gen_reg_rtx (<MODE>mode);
3092 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3093 emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp,
3094 const0_rtx, operands[3]));
3098 (define_expand "neon_vqdmull_n<mode>"
3099 [(match_operand:<V_widen> 0 "s_register_operand" "")
3100 (match_operand:VMDI 1 "s_register_operand" "")
3101 (match_operand:<V_elem> 2 "s_register_operand" "")
3102 (match_operand:SI 3 "immediate_operand" "")]
3105 rtx tmp = gen_reg_rtx (<MODE>mode);
3106 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3107 emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp,
3108 const0_rtx, const0_rtx));
3112 (define_expand "neon_vqdmulh_n<mode>"
3113 [(match_operand:VMDI 0 "s_register_operand" "")
3114 (match_operand:VMDI 1 "s_register_operand" "")
3115 (match_operand:<V_elem> 2 "s_register_operand" "")
3116 (match_operand:SI 3 "immediate_operand" "")]
3119 rtx tmp = gen_reg_rtx (<MODE>mode);
3120 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3121 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3122 const0_rtx, operands[3]));
3126 (define_expand "neon_vqdmulh_n<mode>"
3127 [(match_operand:VMQI 0 "s_register_operand" "")
3128 (match_operand:VMQI 1 "s_register_operand" "")
3129 (match_operand:<V_elem> 2 "s_register_operand" "")
3130 (match_operand:SI 3 "immediate_operand" "")]
3133 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3134 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3135 emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3136 const0_rtx, operands[3]));
3140 (define_expand "neon_vmla_n<mode>"
3141 [(match_operand:VMD 0 "s_register_operand" "")
3142 (match_operand:VMD 1 "s_register_operand" "")
3143 (match_operand:VMD 2 "s_register_operand" "")
3144 (match_operand:<V_elem> 3 "s_register_operand" "")
3145 (match_operand:SI 4 "immediate_operand" "")]
3148 rtx tmp = gen_reg_rtx (<MODE>mode);
3149 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3150 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3151 tmp, const0_rtx, operands[4]));
3155 (define_expand "neon_vmla_n<mode>"
3156 [(match_operand:VMQ 0 "s_register_operand" "")
3157 (match_operand:VMQ 1 "s_register_operand" "")
3158 (match_operand:VMQ 2 "s_register_operand" "")
3159 (match_operand:<V_elem> 3 "s_register_operand" "")
3160 (match_operand:SI 4 "immediate_operand" "")]
3163 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3164 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3165 emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3166 tmp, const0_rtx, operands[4]));
3170 (define_expand "neon_vmlal_n<mode>"
3171 [(match_operand:<V_widen> 0 "s_register_operand" "")
3172 (match_operand:<V_widen> 1 "s_register_operand" "")
3173 (match_operand:VMDI 2 "s_register_operand" "")
3174 (match_operand:<V_elem> 3 "s_register_operand" "")
3175 (match_operand:SI 4 "immediate_operand" "")]
3178 rtx tmp = gen_reg_rtx (<MODE>mode);
3179 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3180 emit_insn (gen_neon_vmlal_lane<mode> (operands[0], operands[1], operands[2],
3181 tmp, const0_rtx, operands[4]));
3185 (define_expand "neon_vqdmlal_n<mode>"
3186 [(match_operand:<V_widen> 0 "s_register_operand" "")
3187 (match_operand:<V_widen> 1 "s_register_operand" "")
3188 (match_operand:VMDI 2 "s_register_operand" "")
3189 (match_operand:<V_elem> 3 "s_register_operand" "")
3190 (match_operand:SI 4 "immediate_operand" "")]
3193 rtx tmp = gen_reg_rtx (<MODE>mode);
3194 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3195 emit_insn (gen_neon_vqdmlal_lane<mode> (operands[0], operands[1], operands[2],
3196 tmp, const0_rtx, operands[4]));
3200 (define_expand "neon_vmls_n<mode>"
3201 [(match_operand:VMD 0 "s_register_operand" "")
3202 (match_operand:VMD 1 "s_register_operand" "")
3203 (match_operand:VMD 2 "s_register_operand" "")
3204 (match_operand:<V_elem> 3 "s_register_operand" "")
3205 (match_operand:SI 4 "immediate_operand" "")]
3208 rtx tmp = gen_reg_rtx (<MODE>mode);
3209 emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3210 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3211 tmp, const0_rtx, operands[4]));
3215 (define_expand "neon_vmls_n<mode>"
3216 [(match_operand:VMQ 0 "s_register_operand" "")
3217 (match_operand:VMQ 1 "s_register_operand" "")
3218 (match_operand:VMQ 2 "s_register_operand" "")
3219 (match_operand:<V_elem> 3 "s_register_operand" "")
3220 (match_operand:SI 4 "immediate_operand" "")]
3223 rtx tmp = gen_reg_rtx (<V_HALF>mode);
3224 emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3225 emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],