1 ;; Machine description for AArch64 AdvSIMD architecture.
2 ;; Copyright (C) 2011-2013 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
22 ; Main data types used by the insntructions
24 (define_attr "simd_mode" "unknown,none,V8QI,V16QI,V4HI,V8HI,V2SI,V4SI,V2DI,V2SF,V4SF,V2DF,OI,CI,XI,DI,DF,SI,HI,QI"
25 (const_string "unknown"))
28 ; Classification of AdvSIMD instructions for scheduling purposes.
29 ; Do not set this attribute and the "v8type" attribute together in
30 ; any instruction pattern.
32 ; simd_abd integer absolute difference and accumulate.
33 ; simd_abdl integer absolute difference and accumulate (long).
34 ; simd_adal integer add and accumulate (long).
35 ; simd_add integer addition/subtraction.
36 ; simd_addl integer addition/subtraction (long).
37 ; simd_addlv across lanes integer sum (long).
38 ; simd_addn integer addition/subtraction (narrow).
39 ; simd_addn2 integer addition/subtraction (narrow, high).
40 ; simd_addv across lanes integer sum.
41 ; simd_cls count leading sign/zero bits.
42 ; simd_cmp compare / create mask.
43 ; simd_cnt population count.
44 ; simd_dup duplicate element.
45 ; simd_dupgp duplicate general purpose register.
46 ; simd_ext bitwise extract from pair.
47 ; simd_fabd floating absolute difference and accumulate.
48 ; simd_fadd floating point add/sub.
49 ; simd_fcmp floating point compare.
50 ; simd_fcvti floating point convert to integer.
51 ; simd_fcvtl floating-point convert upsize.
52 ; simd_fcvtn floating-point convert downsize (narrow).
53 ; simd_fcvtn2 floating-point convert downsize (narrow, high).
54 ; simd_fdiv floating point division.
55 ; simd_fminmax floating point min/max.
56 ; simd_fminmaxv across lanes floating point min/max.
57 ; simd_fmla floating point multiply-add.
58 ; simd_fmla_elt floating point multiply-add (by element).
59 ; simd_fmul floating point multiply.
60 ; simd_fmul_elt floating point multiply (by element).
61 ; simd_fnegabs floating point neg/abs.
62 ; simd_frecpe floating point reciprocal estimate.
63 ; simd_frecps floating point reciprocal step.
64 ; simd_frecpx floating point reciprocal exponent.
65 ; simd_frint floating point round to integer.
66 ; simd_fsqrt floating point square root.
67 ; simd_icvtf integer convert to floating point.
68 ; simd_ins insert element.
69 ; simd_insgp insert general purpose register.
70 ; simd_load1 load multiple structures to one register (LD1).
71 ; simd_load1r load single structure to all lanes of one register (LD1R).
72 ; simd_load1s load single structure to one lane of one register (LD1 [index]).
73 ; simd_load2 load multiple structures to two registers (LD1, LD2).
74 ; simd_load2r load single structure to all lanes of two registers (LD1R, LD2R).
75 ; simd_load2s load single structure to one lane of two registers (LD2 [index]).
76 ; simd_load3 load multiple structures to three registers (LD1, LD3).
77 ; simd_load3r load single structure to all lanes of three registers (LD3R).
78 ; simd_load3s load single structure to one lane of three registers (LD3 [index]).
79 ; simd_load4 load multiple structures to four registers (LD1, LD2, LD4).
80 ; simd_load4r load single structure to all lanes of four registers (LD4R).
81 ; simd_load4s load single structure to one lane of four registers (LD4 [index]).
82 ; simd_logic logical operation.
83 ; simd_logic_imm logcial operation (immediate).
84 ; simd_minmax integer min/max.
85 ; simd_minmaxv across lanes integer min/max,
86 ; simd_mla integer multiply-accumulate.
87 ; simd_mla_elt integer multiply-accumulate (by element).
88 ; simd_mlal integer multiply-accumulate (long).
89 ; simd_mlal_elt integer multiply-accumulate (by element, long).
90 ; simd_move move register.
91 ; simd_move_imm move immediate.
92 ; simd_movgp move element to general purpose register.
93 ; simd_mul integer multiply.
94 ; simd_mul_elt integer multiply (by element).
95 ; simd_mull integer multiply (long).
96 ; simd_mull_elt integer multiply (by element, long).
97 ; simd_negabs integer negate/absolute.
98 ; simd_rbit bitwise reverse.
99 ; simd_rcpe integer reciprocal estimate.
100 ; simd_rcps integer reciprocal square root.
101 ; simd_rev element reverse.
102 ; simd_sat_add integer saturating addition/subtraction.
103 ; simd_sat_mlal integer saturating multiply-accumulate (long).
104 ; simd_sat_mlal_elt integer saturating multiply-accumulate (by element, long).
105 ; simd_sat_mul integer saturating multiply.
106 ; simd_sat_mul_elt integer saturating multiply (by element).
107 ; simd_sat_mull integer saturating multiply (long).
108 ; simd_sat_mull_elt integer saturating multiply (by element, long).
109 ; simd_sat_negabs integer saturating negate/absolute.
110 ; simd_sat_shift integer saturating shift.
111 ; simd_sat_shift_imm integer saturating shift (immediate).
112 ; simd_sat_shiftn_imm integer saturating shift (narrow, immediate).
113 ; simd_sat_shiftn2_imm integer saturating shift (narrow, high, immediate).
114 ; simd_shift shift register/vector.
115 ; simd_shift_acc shift accumulate.
116 ; simd_shift_imm shift immediate.
117 ; simd_shift_imm_acc shift immediate and accumualte.
118 ; simd_shiftl shift register/vector (long).
119 ; simd_shiftl_imm shift register/vector (long, immediate).
120 ; simd_shiftn_imm shift register/vector (narrow, immediate).
121 ; simd_shiftn2_imm shift register/vector (narrow, high, immediate).
122 ; simd_store1 store multiple structures from one register (ST1).
123 ; simd_store1s store single structure from one lane of one register (ST1 [index]).
124 ; simd_store2 store multiple structures from two registers (ST1, ST2).
125 ; simd_store2s store single structure from one lane of two registers (ST2 [index]).
126 ; simd_store3 store multiple structures from three registers (ST1, ST3).
127 ; simd_store3s store single structure from one lane of three register (ST3 [index]).
128 ; simd_store4 store multiple structures from four registers (ST1, ST2, ST4).
129 ; simd_store4s store single structure from one lane for four registers (ST4 [index]).
130 ; simd_tbl table lookup.
131 ; simd_trn transpose.
135 (define_attr "simd_type"
216 simd_sat_shiftn_imm,\
217 simd_sat_shiftn2_imm,\
239 (const_string "none"))
242 ; The "neon_type" attribute is used by the AArch32 backend. Below is a mapping
243 ; from "simd_type" to "neon_type".
245 (define_attr "neon_type"
246 "neon_int_1,neon_int_2,neon_int_3,neon_int_4,neon_int_5,neon_vqneg_vqabs,
247 neon_vmov,neon_vaba,neon_vsma,neon_vaba_qqq,
248 neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,neon_mul_qqq_8_16_32_ddd_32,
249 neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,
250 neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,neon_mla_qqq_8_16,
251 neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,
252 neon_mla_qqq_32_qqd_32_scalar,neon_mul_ddd_16_scalar_32_16_long_scalar,
253 neon_mul_qqd_32_scalar,neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,
254 neon_shift_1,neon_shift_2,neon_shift_3,neon_vshl_ddd,
255 neon_vqshl_vrshl_vqrshl_qqq,neon_vsra_vrsra,neon_fp_vadd_ddd_vabs_dd,
256 neon_fp_vadd_qqq_vabs_qq,neon_fp_vsum,neon_fp_vmul_ddd,neon_fp_vmul_qqd,
257 neon_fp_vmla_ddd,neon_fp_vmla_qqq,neon_fp_vmla_ddd_scalar,
258 neon_fp_vmla_qqq_scalar,neon_fp_vrecps_vrsqrts_ddd,
259 neon_fp_vrecps_vrsqrts_qqq,neon_bp_simple,neon_bp_2cycle,neon_bp_3cycle,
260 neon_ldr,neon_str,neon_vld1_1_2_regs,neon_vld1_3_4_regs,
261 neon_vld2_2_regs_vld1_vld2_all_lanes,neon_vld2_4_regs,neon_vld3_vld4,
262 neon_vst1_1_2_regs_vst2_2_regs,neon_vst1_3_4_regs,
263 neon_vst2_4_regs_vst3_vst4,neon_vst3_vst4,neon_vld1_vld2_lane,
264 neon_vld3_vld4_lane,neon_vst1_vst2_lane,neon_vst3_vst4_lane,
265 neon_vld3_vld4_all_lanes,neon_mcr,neon_mcr_2_mcrr,neon_mrc,neon_mrrc,
266 neon_ldm_2,neon_stm_2,none,unknown"
268 (eq_attr "simd_type" "simd_dup") (const_string "neon_bp_simple")
269 (eq_attr "simd_type" "simd_movgp") (const_string "neon_bp_simple")
270 (eq_attr "simd_type" "simd_add,simd_logic,simd_logic_imm") (const_string "neon_int_1")
271 (eq_attr "simd_type" "simd_negabs,simd_addlv") (const_string "neon_int_3")
272 (eq_attr "simd_type" "simd_addn,simd_addn2,simd_addl,simd_sat_add,simd_sat_negabs") (const_string "neon_int_4")
273 (eq_attr "simd_type" "simd_move") (const_string "neon_vmov")
274 (eq_attr "simd_type" "simd_ins") (const_string "neon_mcr")
275 (and (eq_attr "simd_type" "simd_mul,simd_sat_mul") (eq_attr "simd_mode" "V8QI,V4HI")) (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
276 (and (eq_attr "simd_type" "simd_mul,simd_sat_mul") (eq_attr "simd_mode" "V2SI,V8QI,V16QI,V2SI")) (const_string "neon_mul_qqq_8_16_32_ddd_32")
277 (and (eq_attr "simd_type" "simd_mull,simd_sat_mull") (eq_attr "simd_mode" "V8QI,V16QI,V4HI,V8HI")) (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
278 (and (eq_attr "simd_type" "simd_mull,simd_sat_mull") (eq_attr "simd_mode" "V2SI,V4SI,V2DI")) (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
279 (and (eq_attr "simd_type" "simd_mla,simd_sat_mlal") (eq_attr "simd_mode" "V8QI,V4HI")) (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
280 (and (eq_attr "simd_type" "simd_mla,simd_sat_mlal") (eq_attr "simd_mode" "V2SI")) (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
281 (and (eq_attr "simd_type" "simd_mla,simd_sat_mlal") (eq_attr "simd_mode" "V16QI,V8HI")) (const_string "neon_mla_qqq_8_16")
282 (and (eq_attr "simd_type" "simd_mla,simd_sat_mlal") (eq_attr "simd_mode" "V4SI")) (const_string "neon_mla_qqq_32_qqd_32_scalar")
283 (and (eq_attr "simd_type" "simd_mlal") (eq_attr "simd_mode" "V8QI,V16QI,V4HI,V8HI")) (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
284 (and (eq_attr "simd_type" "simd_mlal") (eq_attr "simd_mode" "V2SI,V4SI,V2DI")) (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
285 (and (eq_attr "simd_type" "simd_fmla") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vmla_ddd")
286 (and (eq_attr "simd_type" "simd_fmla") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vmla_qqq")
287 (and (eq_attr "simd_type" "simd_fmla_elt") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vmla_ddd_scalar")
288 (and (eq_attr "simd_type" "simd_fmla_elt") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vmla_qqq_scalar")
289 (and (eq_attr "simd_type" "simd_fmul,simd_fmul_elt,simd_fdiv,simd_fsqrt") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vmul_ddd")
290 (and (eq_attr "simd_type" "simd_fmul,simd_fmul_elt,simd_fdiv,simd_fsqrt") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vmul_qqd")
291 (and (eq_attr "simd_type" "simd_fadd") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vadd_ddd_vabs_dd")
292 (and (eq_attr "simd_type" "simd_fadd") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vadd_qqq_vabs_qq")
293 (and (eq_attr "simd_type" "simd_fnegabs,simd_fminmax,simd_fminmaxv") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vadd_ddd_vabs_dd")
294 (and (eq_attr "simd_type" "simd_fnegabs,simd_fminmax,simd_fminmaxv") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vadd_qqq_vabs_qq")
295 (and (eq_attr "simd_type" "simd_shift,simd_shift_acc") (eq_attr "simd_mode" "V8QI,V4HI,V2SI")) (const_string "neon_vshl_ddd")
296 (and (eq_attr "simd_type" "simd_shift,simd_shift_acc") (eq_attr "simd_mode" "V16QI,V8HI,V4SI,V2DI")) (const_string "neon_shift_3")
297 (eq_attr "simd_type" "simd_minmax,simd_minmaxv") (const_string "neon_int_5")
298 (eq_attr "simd_type" "simd_shiftn_imm,simd_shiftn2_imm,simd_shiftl_imm,") (const_string "neon_shift_1")
299 (eq_attr "simd_type" "simd_load1,simd_load2") (const_string "neon_vld1_1_2_regs")
300 (eq_attr "simd_type" "simd_load3,simd_load3") (const_string "neon_vld1_3_4_regs")
301 (eq_attr "simd_type" "simd_load1r,simd_load2r,simd_load3r,simd_load4r") (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
302 (eq_attr "simd_type" "simd_load1s,simd_load2s") (const_string "neon_vld1_vld2_lane")
303 (eq_attr "simd_type" "simd_load3s,simd_load4s") (const_string "neon_vld3_vld4_lane")
304 (eq_attr "simd_type" "simd_store1,simd_store2") (const_string "neon_vst1_1_2_regs_vst2_2_regs")
305 (eq_attr "simd_type" "simd_store3,simd_store4") (const_string "neon_vst1_3_4_regs")
306 (eq_attr "simd_type" "simd_store1s,simd_store2s") (const_string "neon_vst1_vst2_lane")
307 (eq_attr "simd_type" "simd_store3s,simd_store4s") (const_string "neon_vst3_vst4_lane")
308 (and (eq_attr "simd_type" "simd_frecpe,simd_frecps") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vrecps_vrsqrts_ddd")
309 (and (eq_attr "simd_type" "simd_frecpe,simd_frecps") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vrecps_vrsqrts_qqq")
310 (eq_attr "simd_type" "none") (const_string "none")
312 (const_string "unknown")))
315 (define_expand "mov<mode>"
316 [(set (match_operand:VALL 0 "aarch64_simd_nonimmediate_operand" "")
317 (match_operand:VALL 1 "aarch64_simd_general_operand" ""))]
320 if (GET_CODE (operands[0]) == MEM)
321 operands[1] = force_reg (<MODE>mode, operands[1]);
325 (define_expand "movmisalign<mode>"
326 [(set (match_operand:VALL 0 "aarch64_simd_nonimmediate_operand" "")
327 (match_operand:VALL 1 "aarch64_simd_general_operand" ""))]
330 /* This pattern is not permitted to fail during expansion: if both arguments
331 are non-registers (e.g. memory := constant, which can be created by the
332 auto-vectorizer), force operand 1 into a register. */
333 if (!register_operand (operands[0], <MODE>mode)
334 && !register_operand (operands[1], <MODE>mode))
335 operands[1] = force_reg (<MODE>mode, operands[1]);
338 (define_insn "aarch64_simd_dup<mode>"
339 [(set (match_operand:VDQ 0 "register_operand" "=w")
340 (vec_duplicate:VDQ (match_operand:<VEL> 1 "register_operand" "r")))]
342 "dup\\t%0.<Vtype>, %<vw>1"
343 [(set_attr "simd_type" "simd_dupgp")
344 (set_attr "simd_mode" "<MODE>")]
347 (define_insn "aarch64_dup_lane<mode>"
348 [(set (match_operand:VDQ_I 0 "register_operand" "=w")
351 (match_operand:<VCON> 1 "register_operand" "w")
352 (parallel [(match_operand:SI 2 "immediate_operand" "i")])
355 "dup\\t%<v>0<Vmtype>, %1.<Vetype>[%2]"
356 [(set_attr "simd_type" "simd_dup")
357 (set_attr "simd_mode" "<MODE>")]
360 (define_insn "aarch64_dup_lane<mode>"
361 [(set (match_operand:SDQ_I 0 "register_operand" "=w")
363 (match_operand:<VCON> 1 "register_operand" "w")
364 (parallel [(match_operand:SI 2 "immediate_operand" "i")])
367 "dup\\t%<v>0<Vmtype>, %1.<Vetype>[%2]"
368 [(set_attr "simd_type" "simd_dup")
369 (set_attr "simd_mode" "<MODE>")]
372 (define_insn "aarch64_simd_dup<mode>"
373 [(set (match_operand:VDQF 0 "register_operand" "=w")
374 (vec_duplicate:VDQF (match_operand:<VEL> 1 "register_operand" "w")))]
376 "dup\\t%0.<Vtype>, %1.<Vetype>[0]"
377 [(set_attr "simd_type" "simd_dup")
378 (set_attr "simd_mode" "<MODE>")]
381 (define_insn "*aarch64_simd_mov<mode>"
382 [(set (match_operand:VD 0 "aarch64_simd_nonimmediate_operand"
383 "=w, Utv, w, ?r, ?w, ?r, w")
384 (match_operand:VD 1 "aarch64_simd_general_operand"
385 "Utv, w, w, w, r, r, Dn"))]
387 && (register_operand (operands[0], <MODE>mode)
388 || register_operand (operands[1], <MODE>mode))"
390 switch (which_alternative)
392 case 0: return "ld1\t{%0.<Vtype>}, %1";
393 case 1: return "st1\t{%1.<Vtype>}, %0";
394 case 2: return "orr\t%0.<Vbtype>, %1.<Vbtype>, %1.<Vbtype>";
395 case 3: return "umov\t%0, %1.d[0]";
396 case 4: return "ins\t%0.d[0], %1";
397 case 5: return "mov\t%0, %1";
399 return aarch64_output_simd_mov_immediate (&operands[1],
401 default: gcc_unreachable ();
404 [(set_attr "simd_type" "simd_load1,simd_store1,simd_move,simd_movgp,simd_insgp,simd_move,simd_move_imm")
405 (set_attr "simd_mode" "<MODE>")]
408 (define_insn "*aarch64_simd_mov<mode>"
409 [(set (match_operand:VQ 0 "aarch64_simd_nonimmediate_operand"
410 "=w, Utv, w, ?r, ?w, ?r, w")
411 (match_operand:VQ 1 "aarch64_simd_general_operand"
412 "Utv, w, w, w, r, r, Dn"))]
414 && (register_operand (operands[0], <MODE>mode)
415 || register_operand (operands[1], <MODE>mode))"
417 switch (which_alternative)
419 case 0: return "ld1\t{%0.<Vtype>}, %1";
420 case 1: return "st1\t{%1.<Vtype>}, %0";
421 case 2: return "orr\t%0.<Vbtype>, %1.<Vbtype>, %1.<Vbtype>";
422 case 3: return "umov\t%0, %1.d[0]\;umov\t%H0, %1.d[1]";
423 case 4: return "ins\t%0.d[0], %1\;ins\t%0.d[1], %H1";
426 return aarch64_output_simd_mov_immediate (&operands[1],
428 default: gcc_unreachable ();
431 [(set_attr "simd_type" "simd_load1,simd_store1,simd_move,simd_movgp,simd_insgp,simd_move,simd_move_imm")
432 (set_attr "simd_mode" "<MODE>")
433 (set_attr "length" "4,4,4,8,8,8,4")]
437 [(set (match_operand:VQ 0 "register_operand" "")
438 (match_operand:VQ 1 "register_operand" ""))]
439 "TARGET_SIMD && reload_completed
440 && GP_REGNUM_P (REGNO (operands[0]))
441 && GP_REGNUM_P (REGNO (operands[1]))"
442 [(set (match_dup 0) (match_dup 1))
443 (set (match_dup 2) (match_dup 3))]
445 int rdest = REGNO (operands[0]);
446 int rsrc = REGNO (operands[1]);
449 dest[0] = gen_rtx_REG (DImode, rdest);
450 src[0] = gen_rtx_REG (DImode, rsrc);
451 dest[1] = gen_rtx_REG (DImode, rdest + 1);
452 src[1] = gen_rtx_REG (DImode, rsrc + 1);
454 aarch64_simd_disambiguate_copy (operands, dest, src, 2);
457 (define_insn "orn<mode>3"
458 [(set (match_operand:VDQ 0 "register_operand" "=w")
459 (ior:VDQ (not:VDQ (match_operand:VDQ 1 "register_operand" "w"))
460 (match_operand:VDQ 2 "register_operand" "w")))]
462 "orn\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
463 [(set_attr "simd_type" "simd_logic")
464 (set_attr "simd_mode" "<MODE>")]
467 (define_insn "bic<mode>3"
468 [(set (match_operand:VDQ 0 "register_operand" "=w")
469 (and:VDQ (not:VDQ (match_operand:VDQ 1 "register_operand" "w"))
470 (match_operand:VDQ 2 "register_operand" "w")))]
472 "bic\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
473 [(set_attr "simd_type" "simd_logic")
474 (set_attr "simd_mode" "<MODE>")]
477 (define_insn "add<mode>3"
478 [(set (match_operand:VDQ 0 "register_operand" "=w")
479 (plus:VDQ (match_operand:VDQ 1 "register_operand" "w")
480 (match_operand:VDQ 2 "register_operand" "w")))]
482 "add\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
483 [(set_attr "simd_type" "simd_add")
484 (set_attr "simd_mode" "<MODE>")]
487 (define_insn "sub<mode>3"
488 [(set (match_operand:VDQ 0 "register_operand" "=w")
489 (minus:VDQ (match_operand:VDQ 1 "register_operand" "w")
490 (match_operand:VDQ 2 "register_operand" "w")))]
492 "sub\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
493 [(set_attr "simd_type" "simd_add")
494 (set_attr "simd_mode" "<MODE>")]
497 (define_insn "mul<mode>3"
498 [(set (match_operand:VDQM 0 "register_operand" "=w")
499 (mult:VDQM (match_operand:VDQM 1 "register_operand" "w")
500 (match_operand:VDQM 2 "register_operand" "w")))]
502 "mul\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
503 [(set_attr "simd_type" "simd_mul")
504 (set_attr "simd_mode" "<MODE>")]
507 (define_insn "neg<mode>2"
508 [(set (match_operand:VDQ 0 "register_operand" "=w")
509 (neg:VDQ (match_operand:VDQ 1 "register_operand" "w")))]
511 "neg\t%0.<Vtype>, %1.<Vtype>"
512 [(set_attr "simd_type" "simd_negabs")
513 (set_attr "simd_mode" "<MODE>")]
516 (define_insn "abs<mode>2"
517 [(set (match_operand:VDQ 0 "register_operand" "=w")
518 (abs:VDQ (match_operand:VDQ 1 "register_operand" "w")))]
520 "abs\t%0.<Vtype>, %1.<Vtype>"
521 [(set_attr "simd_type" "simd_negabs")
522 (set_attr "simd_mode" "<MODE>")]
525 (define_insn "abd<mode>_3"
526 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
527 (abs:VDQ_BHSI (minus:VDQ_BHSI
528 (match_operand:VDQ_BHSI 1 "register_operand" "w")
529 (match_operand:VDQ_BHSI 2 "register_operand" "w"))))]
531 "sabd\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
532 [(set_attr "simd_type" "simd_abd")
533 (set_attr "simd_mode" "<MODE>")]
536 (define_insn "aba<mode>_3"
537 [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
538 (plus:VDQ_BHSI (abs:VDQ_BHSI (minus:VDQ_BHSI
539 (match_operand:VDQ_BHSI 1 "register_operand" "w")
540 (match_operand:VDQ_BHSI 2 "register_operand" "w")))
541 (match_operand:VDQ_BHSI 3 "register_operand" "0")))]
543 "saba\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
544 [(set_attr "simd_type" "simd_abd")
545 (set_attr "simd_mode" "<MODE>")]
548 (define_insn "fabd<mode>_3"
549 [(set (match_operand:VDQF 0 "register_operand" "=w")
550 (abs:VDQF (minus:VDQF
551 (match_operand:VDQF 1 "register_operand" "w")
552 (match_operand:VDQF 2 "register_operand" "w"))))]
554 "fabd\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
555 [(set_attr "simd_type" "simd_fabd")
556 (set_attr "simd_mode" "<MODE>")]
559 (define_insn "and<mode>3"
560 [(set (match_operand:VDQ 0 "register_operand" "=w")
561 (and:VDQ (match_operand:VDQ 1 "register_operand" "w")
562 (match_operand:VDQ 2 "register_operand" "w")))]
564 "and\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
565 [(set_attr "simd_type" "simd_logic")
566 (set_attr "simd_mode" "<MODE>")]
569 (define_insn "ior<mode>3"
570 [(set (match_operand:VDQ 0 "register_operand" "=w")
571 (ior:VDQ (match_operand:VDQ 1 "register_operand" "w")
572 (match_operand:VDQ 2 "register_operand" "w")))]
574 "orr\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
575 [(set_attr "simd_type" "simd_logic")
576 (set_attr "simd_mode" "<MODE>")]
579 (define_insn "xor<mode>3"
580 [(set (match_operand:VDQ 0 "register_operand" "=w")
581 (xor:VDQ (match_operand:VDQ 1 "register_operand" "w")
582 (match_operand:VDQ 2 "register_operand" "w")))]
584 "eor\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
585 [(set_attr "simd_type" "simd_logic")
586 (set_attr "simd_mode" "<MODE>")]
589 (define_insn "one_cmpl<mode>2"
590 [(set (match_operand:VDQ 0 "register_operand" "=w")
591 (not:VDQ (match_operand:VDQ 1 "register_operand" "w")))]
593 "not\t%0.<Vbtype>, %1.<Vbtype>"
594 [(set_attr "simd_type" "simd_logic")
595 (set_attr "simd_mode" "<MODE>")]
598 (define_insn "aarch64_simd_vec_set<mode>"
599 [(set (match_operand:VQ_S 0 "register_operand" "=w")
602 (match_operand:<VEL> 1 "register_operand" "r"))
603 (match_operand:VQ_S 3 "register_operand" "0")
604 (match_operand:SI 2 "immediate_operand" "i")))]
606 "ins\t%0.<Vetype>[%p2], %w1";
607 [(set_attr "simd_type" "simd_insgp")
608 (set_attr "simd_mode" "<MODE>")]
611 (define_insn "aarch64_simd_lshr<mode>"
612 [(set (match_operand:VDQ 0 "register_operand" "=w")
613 (lshiftrt:VDQ (match_operand:VDQ 1 "register_operand" "w")
614 (match_operand:VDQ 2 "aarch64_simd_rshift_imm" "Dr")))]
616 "ushr\t%0.<Vtype>, %1.<Vtype>, %2"
617 [(set_attr "simd_type" "simd_shift_imm")
618 (set_attr "simd_mode" "<MODE>")]
621 (define_insn "aarch64_simd_ashr<mode>"
622 [(set (match_operand:VDQ 0 "register_operand" "=w")
623 (ashiftrt:VDQ (match_operand:VDQ 1 "register_operand" "w")
624 (match_operand:VDQ 2 "aarch64_simd_rshift_imm" "Dr")))]
626 "sshr\t%0.<Vtype>, %1.<Vtype>, %2"
627 [(set_attr "simd_type" "simd_shift_imm")
628 (set_attr "simd_mode" "<MODE>")]
631 (define_insn "aarch64_simd_imm_shl<mode>"
632 [(set (match_operand:VDQ 0 "register_operand" "=w")
633 (ashift:VDQ (match_operand:VDQ 1 "register_operand" "w")
634 (match_operand:VDQ 2 "aarch64_simd_lshift_imm" "Dl")))]
636 "shl\t%0.<Vtype>, %1.<Vtype>, %2"
637 [(set_attr "simd_type" "simd_shift_imm")
638 (set_attr "simd_mode" "<MODE>")]
641 (define_insn "aarch64_simd_reg_sshl<mode>"
642 [(set (match_operand:VDQ 0 "register_operand" "=w")
643 (ashift:VDQ (match_operand:VDQ 1 "register_operand" "w")
644 (match_operand:VDQ 2 "register_operand" "w")))]
646 "sshl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
647 [(set_attr "simd_type" "simd_shift")
648 (set_attr "simd_mode" "<MODE>")]
651 (define_insn "aarch64_simd_reg_shl<mode>_unsigned"
652 [(set (match_operand:VDQ 0 "register_operand" "=w")
653 (unspec:VDQ [(match_operand:VDQ 1 "register_operand" "w")
654 (match_operand:VDQ 2 "register_operand" "w")]
655 UNSPEC_ASHIFT_UNSIGNED))]
657 "ushl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
658 [(set_attr "simd_type" "simd_shift")
659 (set_attr "simd_mode" "<MODE>")]
662 (define_insn "aarch64_simd_reg_shl<mode>_signed"
663 [(set (match_operand:VDQ 0 "register_operand" "=w")
664 (unspec:VDQ [(match_operand:VDQ 1 "register_operand" "w")
665 (match_operand:VDQ 2 "register_operand" "w")]
666 UNSPEC_ASHIFT_SIGNED))]
668 "sshl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
669 [(set_attr "simd_type" "simd_shift")
670 (set_attr "simd_mode" "<MODE>")]
673 (define_expand "ashl<mode>3"
674 [(match_operand:VDQ 0 "register_operand" "")
675 (match_operand:VDQ 1 "register_operand" "")
676 (match_operand:SI 2 "general_operand" "")]
679 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
682 if (CONST_INT_P (operands[2]))
684 shift_amount = INTVAL (operands[2]);
685 if (shift_amount >= 0 && shift_amount < bit_width)
687 rtx tmp = aarch64_simd_gen_const_vector_dup (<MODE>mode,
689 emit_insn (gen_aarch64_simd_imm_shl<mode> (operands[0],
696 operands[2] = force_reg (SImode, operands[2]);
699 else if (MEM_P (operands[2]))
701 operands[2] = force_reg (SImode, operands[2]);
704 if (REG_P (operands[2]))
706 rtx tmp = gen_reg_rtx (<MODE>mode);
707 emit_insn (gen_aarch64_simd_dup<mode> (tmp,
708 convert_to_mode (<VEL>mode,
711 emit_insn (gen_aarch64_simd_reg_sshl<mode> (operands[0], operands[1],
720 (define_expand "lshr<mode>3"
721 [(match_operand:VDQ 0 "register_operand" "")
722 (match_operand:VDQ 1 "register_operand" "")
723 (match_operand:SI 2 "general_operand" "")]
726 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
729 if (CONST_INT_P (operands[2]))
731 shift_amount = INTVAL (operands[2]);
732 if (shift_amount > 0 && shift_amount <= bit_width)
734 rtx tmp = aarch64_simd_gen_const_vector_dup (<MODE>mode,
736 emit_insn (gen_aarch64_simd_lshr<mode> (operands[0],
742 operands[2] = force_reg (SImode, operands[2]);
744 else if (MEM_P (operands[2]))
746 operands[2] = force_reg (SImode, operands[2]);
749 if (REG_P (operands[2]))
751 rtx tmp = gen_reg_rtx (SImode);
752 rtx tmp1 = gen_reg_rtx (<MODE>mode);
753 emit_insn (gen_negsi2 (tmp, operands[2]));
754 emit_insn (gen_aarch64_simd_dup<mode> (tmp1,
755 convert_to_mode (<VEL>mode,
757 emit_insn (gen_aarch64_simd_reg_shl<mode>_unsigned (operands[0],
767 (define_expand "ashr<mode>3"
768 [(match_operand:VDQ 0 "register_operand" "")
769 (match_operand:VDQ 1 "register_operand" "")
770 (match_operand:SI 2 "general_operand" "")]
773 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
776 if (CONST_INT_P (operands[2]))
778 shift_amount = INTVAL (operands[2]);
779 if (shift_amount > 0 && shift_amount <= bit_width)
781 rtx tmp = aarch64_simd_gen_const_vector_dup (<MODE>mode,
783 emit_insn (gen_aarch64_simd_ashr<mode> (operands[0],
789 operands[2] = force_reg (SImode, operands[2]);
791 else if (MEM_P (operands[2]))
793 operands[2] = force_reg (SImode, operands[2]);
796 if (REG_P (operands[2]))
798 rtx tmp = gen_reg_rtx (SImode);
799 rtx tmp1 = gen_reg_rtx (<MODE>mode);
800 emit_insn (gen_negsi2 (tmp, operands[2]));
801 emit_insn (gen_aarch64_simd_dup<mode> (tmp1,
802 convert_to_mode (<VEL>mode,
804 emit_insn (gen_aarch64_simd_reg_shl<mode>_signed (operands[0],
814 (define_expand "vashl<mode>3"
815 [(match_operand:VDQ 0 "register_operand" "")
816 (match_operand:VDQ 1 "register_operand" "")
817 (match_operand:VDQ 2 "register_operand" "")]
820 emit_insn (gen_aarch64_simd_reg_sshl<mode> (operands[0], operands[1],
825 ;; Using mode VQ_S as there is no V2DImode neg!
826 ;; Negating individual lanes most certainly offsets the
827 ;; gain from vectorization.
828 (define_expand "vashr<mode>3"
829 [(match_operand:VQ_S 0 "register_operand" "")
830 (match_operand:VQ_S 1 "register_operand" "")
831 (match_operand:VQ_S 2 "register_operand" "")]
834 rtx neg = gen_reg_rtx (<MODE>mode);
835 emit (gen_neg<mode>2 (neg, operands[2]));
836 emit_insn (gen_aarch64_simd_reg_shl<mode>_signed (operands[0], operands[1],
841 (define_expand "vlshr<mode>3"
842 [(match_operand:VQ_S 0 "register_operand" "")
843 (match_operand:VQ_S 1 "register_operand" "")
844 (match_operand:VQ_S 2 "register_operand" "")]
847 rtx neg = gen_reg_rtx (<MODE>mode);
848 emit (gen_neg<mode>2 (neg, operands[2]));
849 emit_insn (gen_aarch64_simd_reg_shl<mode>_unsigned (operands[0], operands[1],
854 (define_expand "vec_set<mode>"
855 [(match_operand:VQ_S 0 "register_operand" "+w")
856 (match_operand:<VEL> 1 "register_operand" "r")
857 (match_operand:SI 2 "immediate_operand" "")]
860 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
861 emit_insn (gen_aarch64_simd_vec_set<mode> (operands[0], operands[1],
862 GEN_INT (elem), operands[0]));
867 (define_insn "aarch64_simd_vec_setv2di"
868 [(set (match_operand:V2DI 0 "register_operand" "=w")
871 (match_operand:DI 1 "register_operand" "r"))
872 (match_operand:V2DI 3 "register_operand" "0")
873 (match_operand:SI 2 "immediate_operand" "i")))]
875 "ins\t%0.d[%p2], %1";
876 [(set_attr "simd_type" "simd_insgp")
877 (set_attr "simd_mode" "V2DI")]
880 (define_expand "vec_setv2di"
881 [(match_operand:V2DI 0 "register_operand" "+w")
882 (match_operand:DI 1 "register_operand" "r")
883 (match_operand:SI 2 "immediate_operand" "")]
886 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
887 emit_insn (gen_aarch64_simd_vec_setv2di (operands[0], operands[1],
888 GEN_INT (elem), operands[0]));
893 (define_insn "aarch64_simd_vec_set<mode>"
894 [(set (match_operand:VDQF 0 "register_operand" "=w")
897 (match_operand:<VEL> 1 "register_operand" "w"))
898 (match_operand:VDQF 3 "register_operand" "0")
899 (match_operand:SI 2 "immediate_operand" "i")))]
901 "ins\t%0.<Vetype>[%p2], %1.<Vetype>[0]";
902 [(set_attr "simd_type" "simd_ins")
903 (set_attr "simd_mode" "<MODE>")]
906 (define_expand "vec_set<mode>"
907 [(match_operand:VDQF 0 "register_operand" "+w")
908 (match_operand:<VEL> 1 "register_operand" "w")
909 (match_operand:SI 2 "immediate_operand" "")]
912 HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
913 emit_insn (gen_aarch64_simd_vec_set<mode> (operands[0], operands[1],
914 GEN_INT (elem), operands[0]));
920 (define_insn "aarch64_mla<mode>"
921 [(set (match_operand:VQ_S 0 "register_operand" "=w")
922 (plus:VQ_S (mult:VQ_S (match_operand:VQ_S 2 "register_operand" "w")
923 (match_operand:VQ_S 3 "register_operand" "w"))
924 (match_operand:VQ_S 1 "register_operand" "0")))]
926 "mla\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
927 [(set_attr "simd_type" "simd_mla")
928 (set_attr "simd_mode" "<MODE>")]
931 (define_insn "aarch64_mls<mode>"
932 [(set (match_operand:VQ_S 0 "register_operand" "=w")
933 (minus:VQ_S (match_operand:VQ_S 1 "register_operand" "0")
934 (mult:VQ_S (match_operand:VQ_S 2 "register_operand" "w")
935 (match_operand:VQ_S 3 "register_operand" "w"))))]
937 "mls\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
938 [(set_attr "simd_type" "simd_mla")
939 (set_attr "simd_mode" "<MODE>")]
942 ;; Max/Min operations.
943 (define_insn "<maxmin><mode>3"
944 [(set (match_operand:VQ_S 0 "register_operand" "=w")
945 (MAXMIN:VQ_S (match_operand:VQ_S 1 "register_operand" "w")
946 (match_operand:VQ_S 2 "register_operand" "w")))]
948 "<maxmin>\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
949 [(set_attr "simd_type" "simd_minmax")
950 (set_attr "simd_mode" "<MODE>")]
953 ;; Move into low-half clearing high half to 0.
955 (define_insn "move_lo_quad_<mode>"
956 [(set (match_operand:VQ 0 "register_operand" "=w")
958 (match_operand:<VHALF> 1 "register_operand" "w")
959 (vec_duplicate:<VHALF> (const_int 0))))]
962 [(set_attr "simd_type" "simd_dup")
963 (set_attr "simd_mode" "<MODE>")]
966 ;; Move into high-half.
968 (define_insn "aarch64_simd_move_hi_quad_<mode>"
969 [(set (match_operand:VQ 0 "register_operand" "+w")
973 (match_operand:VQ 2 "vect_par_cnst_lo_half" ""))
974 (match_operand:<VHALF> 1 "register_operand" "w")))]
976 "ins\\t%0.d[1], %1.d[0]";
977 [(set_attr "simd_type" "simd_ins")
978 (set_attr "simd_mode" "<MODE>")]
981 (define_expand "move_hi_quad_<mode>"
982 [(match_operand:VQ 0 "register_operand" "")
983 (match_operand:<VHALF> 1 "register_operand" "")]
986 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
987 emit_insn (gen_aarch64_simd_move_hi_quad_<mode> (operands[0],
992 ;; Narrowing operations.
995 (define_insn "aarch64_simd_vec_pack_trunc_<mode>"
996 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
997 (truncate:<VNARROWQ> (match_operand:VQN 1 "register_operand" "w")))]
999 "xtn\\t%0.<Vntype>, %1.<Vtype>"
1000 [(set_attr "simd_type" "simd_shiftn_imm")
1001 (set_attr "simd_mode" "<MODE>")]
1004 (define_expand "vec_pack_trunc_<mode>"
1005 [(match_operand:<VNARROWD> 0 "register_operand" "")
1006 (match_operand:VDN 1 "register_operand" "")
1007 (match_operand:VDN 2 "register_operand" "")]
1010 rtx tempreg = gen_reg_rtx (<VDBL>mode);
1012 emit_insn (gen_move_lo_quad_<Vdbl> (tempreg, operands[1]));
1013 emit_insn (gen_move_hi_quad_<Vdbl> (tempreg, operands[2]));
1014 emit_insn (gen_aarch64_simd_vec_pack_trunc_<Vdbl> (operands[0], tempreg));
1020 (define_insn "vec_pack_trunc_<mode>"
1021 [(set (match_operand:<VNARROWQ2> 0 "register_operand" "+&w")
1022 (vec_concat:<VNARROWQ2>
1023 (truncate:<VNARROWQ> (match_operand:VQN 1 "register_operand" "w"))
1024 (truncate:<VNARROWQ> (match_operand:VQN 2 "register_operand" "w"))))]
1026 "xtn\\t%0.<Vntype>, %1.<Vtype>\;xtn2\\t%0.<V2ntype>, %2.<Vtype>"
1027 [(set_attr "simd_type" "simd_shiftn2_imm")
1028 (set_attr "simd_mode" "<MODE>")
1029 (set_attr "length" "8")]
1032 ;; Widening operations.
1034 (define_insn "aarch64_simd_vec_unpack<su>_lo_<mode>"
1035 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1036 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1037 (match_operand:VQW 1 "register_operand" "w")
1038 (match_operand:VQW 2 "vect_par_cnst_lo_half" "")
1041 "<su>shll %0.<Vwtype>, %1.<Vhalftype>, 0"
1042 [(set_attr "simd_type" "simd_shiftl_imm")
1043 (set_attr "simd_mode" "<MODE>")]
1046 (define_insn "aarch64_simd_vec_unpack<su>_hi_<mode>"
1047 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1048 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1049 (match_operand:VQW 1 "register_operand" "w")
1050 (match_operand:VQW 2 "vect_par_cnst_hi_half" "")
1053 "<su>shll2 %0.<Vwtype>, %1.<Vtype>, 0"
1054 [(set_attr "simd_type" "simd_shiftl_imm")
1055 (set_attr "simd_mode" "<MODE>")]
1058 (define_expand "vec_unpack<su>_hi_<mode>"
1059 [(match_operand:<VWIDE> 0 "register_operand" "")
1060 (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))]
1063 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
1064 emit_insn (gen_aarch64_simd_vec_unpack<su>_hi_<mode> (operands[0],
1070 (define_expand "vec_unpack<su>_lo_<mode>"
1071 [(match_operand:<VWIDE> 0 "register_operand" "")
1072 (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))]
1075 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
1076 emit_insn (gen_aarch64_simd_vec_unpack<su>_lo_<mode> (operands[0],
1082 ;; Widening arithmetic.
1084 (define_insn "aarch64_simd_vec_<su>mult_lo_<mode>"
1085 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1086 (mult:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1087 (match_operand:VQW 1 "register_operand" "w")
1088 (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))
1089 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1090 (match_operand:VQW 2 "register_operand" "w")
1093 "<su>mull\\t%0.<Vwtype>, %1.<Vhalftype>, %2.<Vhalftype>"
1094 [(set_attr "simd_type" "simd_mull")
1095 (set_attr "simd_mode" "<MODE>")]
1098 (define_expand "vec_widen_<su>mult_lo_<mode>"
1099 [(match_operand:<VWIDE> 0 "register_operand" "")
1100 (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))
1101 (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand" ""))]
1104 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
1105 emit_insn (gen_aarch64_simd_vec_<su>mult_lo_<mode> (operands[0],
1112 (define_insn "aarch64_simd_vec_<su>mult_hi_<mode>"
1113 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
1114 (mult:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1115 (match_operand:VQW 1 "register_operand" "w")
1116 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
1117 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
1118 (match_operand:VQW 2 "register_operand" "w")
1121 "<su>mull2\\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
1122 [(set_attr "simd_type" "simd_mull")
1123 (set_attr "simd_mode" "<MODE>")]
1126 (define_expand "vec_widen_<su>mult_hi_<mode>"
1127 [(match_operand:<VWIDE> 0 "register_operand" "")
1128 (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))
1129 (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand" ""))]
1132 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
1133 emit_insn (gen_aarch64_simd_vec_<su>mult_hi_<mode> (operands[0],
1141 ;; FP vector operations.
1142 ;; AArch64 AdvSIMD supports single-precision (32-bit) and
1143 ;; double-precision (64-bit) floating-point data types and arithmetic as
1144 ;; defined by the IEEE 754-2008 standard. This makes them vectorizable
1145 ;; without the need for -ffast-math or -funsafe-math-optimizations.
1147 ;; Floating-point operations can raise an exception. Vectorizing such
1148 ;; operations are safe because of reasons explained below.
1150 ;; ARMv8 permits an extension to enable trapped floating-point
1151 ;; exception handling, however this is an optional feature. In the
1152 ;; event of a floating-point exception being raised by vectorised
1154 ;; 1. If trapped floating-point exceptions are available, then a trap
1155 ;; will be taken when any lane raises an enabled exception. A trap
1156 ;; handler may determine which lane raised the exception.
1157 ;; 2. Alternatively a sticky exception flag is set in the
1158 ;; floating-point status register (FPSR). Software may explicitly
1159 ;; test the exception flags, in which case the tests will either
1160 ;; prevent vectorisation, allowing precise identification of the
1161 ;; failing operation, or if tested outside of vectorisable regions
1162 ;; then the specific operation and lane are not of interest.
1164 ;; FP arithmetic operations.
1166 (define_insn "add<mode>3"
1167 [(set (match_operand:VDQF 0 "register_operand" "=w")
1168 (plus:VDQF (match_operand:VDQF 1 "register_operand" "w")
1169 (match_operand:VDQF 2 "register_operand" "w")))]
1171 "fadd\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1172 [(set_attr "simd_type" "simd_fadd")
1173 (set_attr "simd_mode" "<MODE>")]
1176 (define_insn "sub<mode>3"
1177 [(set (match_operand:VDQF 0 "register_operand" "=w")
1178 (minus:VDQF (match_operand:VDQF 1 "register_operand" "w")
1179 (match_operand:VDQF 2 "register_operand" "w")))]
1181 "fsub\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1182 [(set_attr "simd_type" "simd_fadd")
1183 (set_attr "simd_mode" "<MODE>")]
1186 (define_insn "mul<mode>3"
1187 [(set (match_operand:VDQF 0 "register_operand" "=w")
1188 (mult:VDQF (match_operand:VDQF 1 "register_operand" "w")
1189 (match_operand:VDQF 2 "register_operand" "w")))]
1191 "fmul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1192 [(set_attr "simd_type" "simd_fmul")
1193 (set_attr "simd_mode" "<MODE>")]
1196 (define_insn "div<mode>3"
1197 [(set (match_operand:VDQF 0 "register_operand" "=w")
1198 (div:VDQF (match_operand:VDQF 1 "register_operand" "w")
1199 (match_operand:VDQF 2 "register_operand" "w")))]
1201 "fdiv\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1202 [(set_attr "simd_type" "simd_fdiv")
1203 (set_attr "simd_mode" "<MODE>")]
1206 (define_insn "neg<mode>2"
1207 [(set (match_operand:VDQF 0 "register_operand" "=w")
1208 (neg:VDQF (match_operand:VDQF 1 "register_operand" "w")))]
1210 "fneg\\t%0.<Vtype>, %1.<Vtype>"
1211 [(set_attr "simd_type" "simd_fnegabs")
1212 (set_attr "simd_mode" "<MODE>")]
1215 (define_insn "abs<mode>2"
1216 [(set (match_operand:VDQF 0 "register_operand" "=w")
1217 (abs:VDQF (match_operand:VDQF 1 "register_operand" "w")))]
1219 "fabs\\t%0.<Vtype>, %1.<Vtype>"
1220 [(set_attr "simd_type" "simd_fnegabs")
1221 (set_attr "simd_mode" "<MODE>")]
1224 (define_insn "fma<mode>4"
1225 [(set (match_operand:VDQF 0 "register_operand" "=w")
1226 (fma:VDQF (match_operand:VDQF 1 "register_operand" "w")
1227 (match_operand:VDQF 2 "register_operand" "w")
1228 (match_operand:VDQF 3 "register_operand" "0")))]
1230 "fmla\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1231 [(set_attr "simd_type" "simd_fmla")
1232 (set_attr "simd_mode" "<MODE>")]
1235 ;; Vector versions of the floating-point frint patterns.
1236 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round.
1237 (define_insn "<frint_pattern><mode>2"
1238 [(set (match_operand:VDQF 0 "register_operand" "=w")
1239 (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")]
1242 "frint<frint_suffix>\\t%0.<Vtype>, %1.<Vtype>"
1243 [(set_attr "simd_type" "simd_frint")
1244 (set_attr "simd_mode" "<MODE>")]
1247 ;; Vector versions of the fcvt standard patterns.
1248 ;; Expands to lbtrunc, lround, lceil, lfloor
1249 (define_insn "l<fcvt_pattern><su_optab><VDQF:mode><fcvt_target>2"
1250 [(set (match_operand:<FCVT_TARGET> 0 "register_operand" "=w")
1251 (FIXUORS:<FCVT_TARGET> (unspec:<FCVT_TARGET>
1252 [(match_operand:VDQF 1 "register_operand" "w")]
1255 "fcvt<frint_suffix><su>\\t%0.<Vtype>, %1.<Vtype>"
1256 [(set_attr "simd_type" "simd_fcvti")
1257 (set_attr "simd_mode" "<MODE>")]
1260 (define_insn "<optab><fcvt_target><VDQF:mode>2"
1261 [(set (match_operand:VDQF 0 "register_operand" "=w")
1263 (match_operand:<FCVT_TARGET> 1 "register_operand" "w")))]
1265 "<su_optab>cvtf\\t%0.<Vtype>, %1.<Vtype>"
1266 [(set_attr "simd_type" "simd_icvtf")
1267 (set_attr "simd_mode" "<MODE>")]
1270 ;; Conversions between vectors of floats and doubles.
1271 ;; Contains a mix of patterns to match standard pattern names
1272 ;; and those for intrinsics.
1274 ;; Float widening operations.
1276 (define_insn "vec_unpacks_lo_v4sf"
1277 [(set (match_operand:V2DF 0 "register_operand" "=w")
1280 (match_operand:V4SF 1 "register_operand" "w")
1281 (parallel [(const_int 0) (const_int 1)])
1284 "fcvtl\\t%0.2d, %1.2s"
1285 [(set_attr "simd_type" "simd_fcvtl")
1286 (set_attr "simd_mode" "V2DF")]
1289 (define_insn "aarch64_float_extend_lo_v2df"
1290 [(set (match_operand:V2DF 0 "register_operand" "=w")
1292 (match_operand:V2SF 1 "register_operand" "w")))]
1294 "fcvtl\\t%0.2d, %1.2s"
1295 [(set_attr "simd_type" "simd_fcvtl")
1296 (set_attr "simd_mode" "V2DF")]
1299 (define_insn "vec_unpacks_hi_v4sf"
1300 [(set (match_operand:V2DF 0 "register_operand" "=w")
1303 (match_operand:V4SF 1 "register_operand" "w")
1304 (parallel [(const_int 2) (const_int 3)])
1307 "fcvtl2\\t%0.2d, %1.4s"
1308 [(set_attr "simd_type" "simd_fcvtl")
1309 (set_attr "simd_mode" "V2DF")]
1312 ;; Float narrowing operations.
1314 (define_insn "aarch64_float_truncate_lo_v2sf"
1315 [(set (match_operand:V2SF 0 "register_operand" "=w")
1316 (float_truncate:V2SF
1317 (match_operand:V2DF 1 "register_operand" "w")))]
1319 "fcvtn\\t%0.2s, %1.2d"
1320 [(set_attr "simd_type" "simd_fcvtl")
1321 (set_attr "simd_mode" "V2SF")]
1324 (define_insn "aarch64_float_truncate_hi_v4sf"
1325 [(set (match_operand:V4SF 0 "register_operand" "=w")
1327 (match_operand:V2SF 1 "register_operand" "0")
1328 (float_truncate:V2SF
1329 (match_operand:V2DF 2 "register_operand" "w"))))]
1331 "fcvtn2\\t%0.4s, %2.2d"
1332 [(set_attr "simd_type" "simd_fcvtl")
1333 (set_attr "simd_mode" "V4SF")]
1336 (define_expand "vec_pack_trunc_v2df"
1337 [(set (match_operand:V4SF 0 "register_operand")
1339 (float_truncate:V2SF
1340 (match_operand:V2DF 1 "register_operand"))
1341 (float_truncate:V2SF
1342 (match_operand:V2DF 2 "register_operand"))
1346 rtx tmp = gen_reg_rtx (V2SFmode);
1347 emit_insn (gen_aarch64_float_truncate_lo_v2sf (tmp, operands[1]));
1348 emit_insn (gen_aarch64_float_truncate_hi_v4sf (operands[0],
1354 (define_expand "vec_pack_trunc_df"
1355 [(set (match_operand:V2SF 0 "register_operand")
1358 (match_operand:DF 1 "register_operand"))
1360 (match_operand:DF 2 "register_operand"))
1364 rtx tmp = gen_reg_rtx (V2SFmode);
1365 emit_insn (gen_move_lo_quad_v2df (tmp, operands[1]));
1366 emit_insn (gen_move_hi_quad_v2df (tmp, operands[2]));
1367 emit_insn (gen_aarch64_float_truncate_lo_v2sf (operands[0], tmp));
1372 (define_insn "aarch64_vmls<mode>"
1373 [(set (match_operand:VDQF 0 "register_operand" "=w")
1374 (minus:VDQF (match_operand:VDQF 1 "register_operand" "0")
1375 (mult:VDQF (match_operand:VDQF 2 "register_operand" "w")
1376 (match_operand:VDQF 3 "register_operand" "w"))))]
1378 "fmls\\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
1379 [(set_attr "simd_type" "simd_fmla")
1380 (set_attr "simd_mode" "<MODE>")]
1384 ;; Max/Min are introduced by idiom recognition by GCC's mid-end. An
1386 ;; a = (b < c) ? b : c;
1387 ;; is idiom-matched as MIN_EXPR<b,c> only if -ffinite-math-only is enabled
1388 ;; either explicitly or indirectly via -ffast-math.
1390 ;; MIN_EXPR and MAX_EXPR eventually map to 'smin' and 'smax' in RTL.
1391 ;; The 'smax' and 'smin' RTL standard pattern names do not specify which
1392 ;; operand will be returned when both operands are zero (i.e. they may not
1393 ;; honour signed zeroes), or when either operand is NaN. Therefore GCC
1394 ;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring
1397 (define_insn "smax<mode>3"
1398 [(set (match_operand:VDQF 0 "register_operand" "=w")
1399 (smax:VDQF (match_operand:VDQF 1 "register_operand" "w")
1400 (match_operand:VDQF 2 "register_operand" "w")))]
1402 "fmaxnm\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1403 [(set_attr "simd_type" "simd_fminmax")
1404 (set_attr "simd_mode" "<MODE>")]
1407 (define_insn "smin<mode>3"
1408 [(set (match_operand:VDQF 0 "register_operand" "=w")
1409 (smin:VDQF (match_operand:VDQF 1 "register_operand" "w")
1410 (match_operand:VDQF 2 "register_operand" "w")))]
1412 "fminnm\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
1413 [(set_attr "simd_type" "simd_fminmax")
1414 (set_attr "simd_mode" "<MODE>")]
1417 ;; FP 'across lanes' max and min ops.
1419 (define_insn "reduc_s<fmaxminv>_v4sf"
1420 [(set (match_operand:V4SF 0 "register_operand" "=w")
1421 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")]
1424 "f<fmaxminv>nmv\\t%s0, %1.4s";
1425 [(set_attr "simd_type" "simd_fminmaxv")
1426 (set_attr "simd_mode" "V4SF")]
1429 (define_insn "reduc_s<fmaxminv>_<mode>"
1430 [(set (match_operand:V2F 0 "register_operand" "=w")
1431 (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
1434 "f<fmaxminv>nmp\\t%0.<Vtype>, %1.<Vtype>, %1.<Vtype>";
1435 [(set_attr "simd_type" "simd_fminmax")
1436 (set_attr "simd_mode" "<MODE>")]
1439 ;; FP 'across lanes' add.
1441 (define_insn "aarch64_addpv4sf"
1442 [(set (match_operand:V4SF 0 "register_operand" "=w")
1443 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")]
1446 "faddp\\t%0.4s, %1.4s, %1.4s"
1447 [(set_attr "simd_type" "simd_fadd")
1448 (set_attr "simd_mode" "V4SF")]
1451 (define_expand "reduc_uplus_v4sf"
1452 [(set (match_operand:V4SF 0 "register_operand" "=w")
1453 (match_operand:V4SF 1 "register_operand" "w"))]
1456 rtx tmp = gen_reg_rtx (V4SFmode);
1457 emit_insn (gen_aarch64_addpv4sf (tmp, operands[1]));
1458 emit_insn (gen_aarch64_addpv4sf (operands[0], tmp));
1462 (define_expand "reduc_splus_v4sf"
1463 [(set (match_operand:V4SF 0 "register_operand" "=w")
1464 (match_operand:V4SF 1 "register_operand" "w"))]
1467 rtx tmp = gen_reg_rtx (V4SFmode);
1468 emit_insn (gen_aarch64_addpv4sf (tmp, operands[1]));
1469 emit_insn (gen_aarch64_addpv4sf (operands[0], tmp));
1473 (define_expand "aarch64_addvv4sf"
1474 [(set (match_operand:V4SF 0 "register_operand" "=w")
1475 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")]
1479 emit_insn (gen_reduc_splus_v4sf (operands[0], operands[1]));
1483 (define_insn "aarch64_addv<mode>"
1484 [(set (match_operand:V2F 0 "register_operand" "=w")
1485 (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
1488 "faddp\\t%<Vetype>0, %1.<Vtype>"
1489 [(set_attr "simd_type" "simd_fadd")
1490 (set_attr "simd_mode" "<MODE>")]
1493 (define_expand "reduc_uplus_<mode>"
1494 [(set (match_operand:V2F 0 "register_operand" "=w")
1495 (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
1501 (define_expand "reduc_splus_<mode>"
1502 [(set (match_operand:V2F 0 "register_operand" "=w")
1503 (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
1509 ;; Reduction across lanes.
1511 (define_insn "aarch64_addv<mode>"
1512 [(set (match_operand:VDQV 0 "register_operand" "=w")
1513 (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
1516 "addv\\t%<Vetype>0, %1.<Vtype>"
1517 [(set_attr "simd_type" "simd_addv")
1518 (set_attr "simd_mode" "<MODE>")]
1521 (define_expand "reduc_splus_<mode>"
1522 [(set (match_operand:VDQV 0 "register_operand" "=w")
1523 (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
1529 (define_expand "reduc_uplus_<mode>"
1530 [(set (match_operand:VDQV 0 "register_operand" "=w")
1531 (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
1537 (define_insn "aarch64_addvv2di"
1538 [(set (match_operand:V2DI 0 "register_operand" "=w")
1539 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")]
1543 [(set_attr "simd_type" "simd_add")
1544 (set_attr "simd_mode" "V2DI")]
1547 (define_expand "reduc_uplus_v2di"
1548 [(set (match_operand:V2DI 0 "register_operand" "=w")
1549 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")]
1555 (define_expand "reduc_splus_v2di"
1556 [(set (match_operand:V2DI 0 "register_operand" "=w")
1557 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")]
1563 (define_insn "aarch64_addvv2si"
1564 [(set (match_operand:V2SI 0 "register_operand" "=w")
1565 (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
1568 "addp\\t%0.2s, %1.2s, %1.2s"
1569 [(set_attr "simd_type" "simd_add")
1570 (set_attr "simd_mode" "V2SI")]
1573 (define_expand "reduc_uplus_v2si"
1574 [(set (match_operand:V2SI 0 "register_operand" "=w")
1575 (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
1581 (define_expand "reduc_splus_v2si"
1582 [(set (match_operand:V2SI 0 "register_operand" "=w")
1583 (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
1589 (define_insn "reduc_<maxminv>_<mode>"
1590 [(set (match_operand:VDQV 0 "register_operand" "=w")
1591 (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
1594 "<maxminv>v\\t%<Vetype>0, %1.<Vtype>"
1595 [(set_attr "simd_type" "simd_minmaxv")
1596 (set_attr "simd_mode" "<MODE>")]
1599 (define_insn "reduc_<maxminv>_v2si"
1600 [(set (match_operand:V2SI 0 "register_operand" "=w")
1601 (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
1604 "<maxminv>p\\t%0.2s, %1.2s, %1.2s"
1605 [(set_attr "simd_type" "simd_minmax")
1606 (set_attr "simd_mode" "V2SI")]
1609 ;; aarch64_simd_bsl may compile to any of bsl/bif/bit depending on register
1611 ;; Operand 1 is the mask, operands 2 and 3 are the bitfields from which
1614 ;; Thus our BSL is of the form:
1615 ;; op0 = bsl (mask, op2, op3)
1616 ;; We can use any of:
1619 ;; bsl mask, op1, op2
1620 ;; if (op0 = op1) (so 1-bits in mask choose bits from op2, else op0)
1621 ;; bit op0, op2, mask
1622 ;; if (op0 = op2) (so 0-bits in mask choose bits from op1, else op0)
1623 ;; bif op0, op1, mask
1625 (define_insn "aarch64_simd_bsl<mode>_internal"
1626 [(set (match_operand:VALL 0 "register_operand" "=w,w,w")
1629 (match_operand:<V_cmp_result> 1 "register_operand" " 0,w,w")
1630 (match_operand:VALL 2 "register_operand" " w,w,0"))
1633 (match_dup:<V_cmp_result> 1))
1634 (match_operand:VALL 3 "register_operand" " w,0,w"))
1638 bsl\\t%0.<Vbtype>, %2.<Vbtype>, %3.<Vbtype>
1639 bit\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>
1640 bif\\t%0.<Vbtype>, %3.<Vbtype>, %1.<Vbtype>"
1643 (define_expand "aarch64_simd_bsl<mode>"
1644 [(match_operand:VALL 0 "register_operand")
1645 (match_operand:<V_cmp_result> 1 "register_operand")
1646 (match_operand:VALL 2 "register_operand")
1647 (match_operand:VALL 3 "register_operand")]
1650 /* We can't alias operands together if they have different modes. */
1651 operands[1] = gen_lowpart (<V_cmp_result>mode, operands[1]);
1652 emit_insn (gen_aarch64_simd_bsl<mode>_internal (operands[0], operands[1],
1653 operands[2], operands[3]));
1657 (define_expand "aarch64_vcond_internal<mode>"
1658 [(set (match_operand:VDQ 0 "register_operand")
1660 (match_operator 3 "comparison_operator"
1661 [(match_operand:VDQ 4 "register_operand")
1662 (match_operand:VDQ 5 "nonmemory_operand")])
1663 (match_operand:VDQ 1 "register_operand")
1664 (match_operand:VDQ 2 "register_operand")))]
1667 int inverse = 0, has_zero_imm_form = 0;
1668 rtx mask = gen_reg_rtx (<MODE>mode);
1670 switch (GET_CODE (operands[3]))
1680 has_zero_imm_form = 1;
1690 if (!REG_P (operands[5])
1691 && (operands[5] != CONST0_RTX (<MODE>mode) || !has_zero_imm_form))
1692 operands[5] = force_reg (<MODE>mode, operands[5]);
1694 switch (GET_CODE (operands[3]))
1698 emit_insn (gen_aarch64_cmge<mode> (mask, operands[4], operands[5]));
1703 emit_insn (gen_aarch64_cmgt<mode> (mask, operands[4], operands[5]));
1708 emit_insn (gen_aarch64_cmhs<mode> (mask, operands[4], operands[5]));
1713 emit_insn (gen_aarch64_cmhi<mode> (mask, operands[4], operands[5]));
1718 emit_insn (gen_aarch64_cmeq<mode> (mask, operands[4], operands[5]));
1726 emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask, operands[2],
1729 emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask, operands[1],
1735 (define_expand "aarch64_vcond_internal<mode>"
1736 [(set (match_operand:VDQF 0 "register_operand")
1738 (match_operator 3 "comparison_operator"
1739 [(match_operand:VDQF 4 "register_operand")
1740 (match_operand:VDQF 5 "nonmemory_operand")])
1741 (match_operand:VDQF 1 "register_operand")
1742 (match_operand:VDQF 2 "register_operand")))]
1746 int use_zero_form = 0;
1747 int swap_bsl_operands = 0;
1748 rtx mask = gen_reg_rtx (<V_cmp_result>mode);
1749 rtx tmp = gen_reg_rtx (<V_cmp_result>mode);
1751 rtx (*base_comparison) (rtx, rtx, rtx);
1752 rtx (*complimentary_comparison) (rtx, rtx, rtx);
1754 switch (GET_CODE (operands[3]))
1761 if (operands[5] == CONST0_RTX (<MODE>mode))
1768 if (!REG_P (operands[5]))
1769 operands[5] = force_reg (<MODE>mode, operands[5]);
1772 switch (GET_CODE (operands[3]))
1782 base_comparison = gen_aarch64_cmge<mode>;
1783 complimentary_comparison = gen_aarch64_cmgt<mode>;
1791 base_comparison = gen_aarch64_cmgt<mode>;
1792 complimentary_comparison = gen_aarch64_cmge<mode>;
1797 base_comparison = gen_aarch64_cmeq<mode>;
1798 complimentary_comparison = gen_aarch64_cmeq<mode>;
1804 switch (GET_CODE (operands[3]))
1811 /* The easy case. Here we emit one of FCMGE, FCMGT or FCMEQ.
1812 As a LT b <=> b GE a && a LE b <=> b GT a. Our transformations are:
1818 Note that there also exist direct comparison against 0 forms,
1819 so catch those as a special case. */
1823 switch (GET_CODE (operands[3]))
1826 base_comparison = gen_aarch64_cmlt<mode>;
1829 base_comparison = gen_aarch64_cmle<mode>;
1832 /* Do nothing, other zero form cases already have the correct
1839 emit_insn (base_comparison (mask, operands[4], operands[5]));
1841 emit_insn (complimentary_comparison (mask, operands[5], operands[4]));
1848 /* FCM returns false for lanes which are unordered, so if we use
1849 the inverse of the comparison we actually want to emit, then
1850 swap the operands to BSL, we will end up with the correct result.
1851 Note that a NE NaN and NaN NE b are true for all a, b.
1853 Our transformations are:
1858 a NE b -> !(a EQ b) */
1861 emit_insn (base_comparison (mask, operands[4], operands[5]));
1863 emit_insn (complimentary_comparison (mask, operands[5], operands[4]));
1865 swap_bsl_operands = 1;
1868 /* We check (a > b || b > a). combining these comparisons give us
1869 true iff !(a != b && a ORDERED b), swapping the operands to BSL
1870 will then give us (a == b || a UNORDERED b) as intended. */
1872 emit_insn (gen_aarch64_cmgt<mode> (mask, operands[4], operands[5]));
1873 emit_insn (gen_aarch64_cmgt<mode> (tmp, operands[5], operands[4]));
1874 emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
1875 swap_bsl_operands = 1;
1878 /* Operands are ORDERED iff (a > b || b >= a).
1879 Swapping the operands to BSL will give the UNORDERED case. */
1880 swap_bsl_operands = 1;
1883 emit_insn (gen_aarch64_cmgt<mode> (tmp, operands[4], operands[5]));
1884 emit_insn (gen_aarch64_cmge<mode> (mask, operands[5], operands[4]));
1885 emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
1891 if (swap_bsl_operands)
1892 emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask, operands[2],
1895 emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask, operands[1],
1900 (define_expand "vcond<mode><mode>"
1901 [(set (match_operand:VALL 0 "register_operand")
1903 (match_operator 3 "comparison_operator"
1904 [(match_operand:VALL 4 "register_operand")
1905 (match_operand:VALL 5 "nonmemory_operand")])
1906 (match_operand:VALL 1 "register_operand")
1907 (match_operand:VALL 2 "register_operand")))]
1910 emit_insn (gen_aarch64_vcond_internal<mode> (operands[0], operands[1],
1911 operands[2], operands[3],
1912 operands[4], operands[5]));
1917 (define_expand "vcondu<mode><mode>"
1918 [(set (match_operand:VDQ 0 "register_operand")
1920 (match_operator 3 "comparison_operator"
1921 [(match_operand:VDQ 4 "register_operand")
1922 (match_operand:VDQ 5 "nonmemory_operand")])
1923 (match_operand:VDQ 1 "register_operand")
1924 (match_operand:VDQ 2 "register_operand")))]
1927 emit_insn (gen_aarch64_vcond_internal<mode> (operands[0], operands[1],
1928 operands[2], operands[3],
1929 operands[4], operands[5]));
1933 ;; Patterns for AArch64 SIMD Intrinsics.
1935 (define_expand "aarch64_create<mode>"
1936 [(match_operand:VD_RE 0 "register_operand" "")
1937 (match_operand:DI 1 "general_operand" "")]
1940 rtx src = gen_lowpart (<MODE>mode, operands[1]);
1941 emit_move_insn (operands[0], src);
1945 (define_insn "aarch64_get_lane_signed<mode>"
1946 [(set (match_operand:<VEL> 0 "register_operand" "=r")
1949 (match_operand:VQ_S 1 "register_operand" "w")
1950 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
1952 "smov\\t%0, %1.<Vetype>[%2]"
1953 [(set_attr "simd_type" "simd_movgp")
1954 (set_attr "simd_mode" "<MODE>")]
1957 (define_insn "aarch64_get_lane_unsigned<mode>"
1958 [(set (match_operand:<VEL> 0 "register_operand" "=r")
1961 (match_operand:VDQ 1 "register_operand" "w")
1962 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
1964 "umov\\t%<vw>0, %1.<Vetype>[%2]"
1965 [(set_attr "simd_type" "simd_movgp")
1966 (set_attr "simd_mode" "<MODE>")]
1969 (define_insn "aarch64_get_lane<mode>"
1970 [(set (match_operand:<VEL> 0 "register_operand" "=w")
1972 (match_operand:VDQF 1 "register_operand" "w")
1973 (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
1975 "mov\\t%0.<Vetype>[0], %1.<Vetype>[%2]"
1976 [(set_attr "simd_type" "simd_ins")
1977 (set_attr "simd_mode" "<MODE>")]
1980 (define_expand "aarch64_get_lanedi"
1981 [(match_operand:DI 0 "register_operand" "=r")
1982 (match_operand:DI 1 "register_operand" "w")
1983 (match_operand:SI 2 "immediate_operand" "i")]
1986 aarch64_simd_lane_bounds (operands[2], 0, 1);
1987 emit_move_insn (operands[0], operands[1]);
1991 (define_expand "aarch64_reinterpretv8qi<mode>"
1992 [(match_operand:V8QI 0 "register_operand" "")
1993 (match_operand:VDC 1 "register_operand" "")]
1996 aarch64_simd_reinterpret (operands[0], operands[1]);
2000 (define_expand "aarch64_reinterpretv4hi<mode>"
2001 [(match_operand:V4HI 0 "register_operand" "")
2002 (match_operand:VDC 1 "register_operand" "")]
2005 aarch64_simd_reinterpret (operands[0], operands[1]);
2009 (define_expand "aarch64_reinterpretv2si<mode>"
2010 [(match_operand:V2SI 0 "register_operand" "")
2011 (match_operand:VDC 1 "register_operand" "")]
2014 aarch64_simd_reinterpret (operands[0], operands[1]);
2018 (define_expand "aarch64_reinterpretv2sf<mode>"
2019 [(match_operand:V2SF 0 "register_operand" "")
2020 (match_operand:VDC 1 "register_operand" "")]
2023 aarch64_simd_reinterpret (operands[0], operands[1]);
2027 (define_expand "aarch64_reinterpretdi<mode>"
2028 [(match_operand:DI 0 "register_operand" "")
2029 (match_operand:VD_RE 1 "register_operand" "")]
2032 aarch64_simd_reinterpret (operands[0], operands[1]);
2036 (define_expand "aarch64_reinterpretv16qi<mode>"
2037 [(match_operand:V16QI 0 "register_operand" "")
2038 (match_operand:VQ 1 "register_operand" "")]
2041 aarch64_simd_reinterpret (operands[0], operands[1]);
2045 (define_expand "aarch64_reinterpretv8hi<mode>"
2046 [(match_operand:V8HI 0 "register_operand" "")
2047 (match_operand:VQ 1 "register_operand" "")]
2050 aarch64_simd_reinterpret (operands[0], operands[1]);
2054 (define_expand "aarch64_reinterpretv4si<mode>"
2055 [(match_operand:V4SI 0 "register_operand" "")
2056 (match_operand:VQ 1 "register_operand" "")]
2059 aarch64_simd_reinterpret (operands[0], operands[1]);
2063 (define_expand "aarch64_reinterpretv4sf<mode>"
2064 [(match_operand:V4SF 0 "register_operand" "")
2065 (match_operand:VQ 1 "register_operand" "")]
2068 aarch64_simd_reinterpret (operands[0], operands[1]);
2072 (define_expand "aarch64_reinterpretv2di<mode>"
2073 [(match_operand:V2DI 0 "register_operand" "")
2074 (match_operand:VQ 1 "register_operand" "")]
2077 aarch64_simd_reinterpret (operands[0], operands[1]);
2081 (define_expand "aarch64_reinterpretv2df<mode>"
2082 [(match_operand:V2DF 0 "register_operand" "")
2083 (match_operand:VQ 1 "register_operand" "")]
2086 aarch64_simd_reinterpret (operands[0], operands[1]);
2090 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
2093 (define_insn "*aarch64_combinez<mode>"
2094 [(set (match_operand:<VDBL> 0 "register_operand" "=&w")
2096 (match_operand:VDIC 1 "register_operand" "w")
2097 (match_operand:VDIC 2 "aarch64_simd_imm_zero" "Dz")))]
2099 "mov\\t%0.8b, %1.8b"
2100 [(set_attr "simd_type" "simd_move")
2101 (set_attr "simd_mode" "<MODE>")]
2104 (define_insn "aarch64_combine<mode>"
2105 [(set (match_operand:<VDBL> 0 "register_operand" "=&w")
2106 (vec_concat:<VDBL> (match_operand:VDC 1 "register_operand" "w")
2107 (match_operand:VDC 2 "register_operand" "w")))]
2109 "mov\\t%0.d[0], %1.d[0]\;ins\\t%0.d[1], %2.d[0]"
2110 [(set_attr "simd_type" "simd_ins")
2111 (set_attr "simd_mode" "<MODE>")]
2114 ;; <su><addsub>l<q>.
2116 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l2<mode>_internal"
2117 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2118 (ADDSUB:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2119 (match_operand:VQW 1 "register_operand" "w")
2120 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
2121 (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
2122 (match_operand:VQW 2 "register_operand" "w")
2125 "<ANY_EXTEND:su><ADDSUB:optab>l2 %0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
2126 [(set_attr "simd_type" "simd_addl")
2127 (set_attr "simd_mode" "<MODE>")]
2130 (define_expand "aarch64_saddl2<mode>"
2131 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2132 (match_operand:VQW 1 "register_operand" "w")
2133 (match_operand:VQW 2 "register_operand" "w")]
2136 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2137 emit_insn (gen_aarch64_saddl2<mode>_internal (operands[0], operands[1],
2142 (define_expand "aarch64_uaddl2<mode>"
2143 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2144 (match_operand:VQW 1 "register_operand" "w")
2145 (match_operand:VQW 2 "register_operand" "w")]
2148 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2149 emit_insn (gen_aarch64_uaddl2<mode>_internal (operands[0], operands[1],
2154 (define_expand "aarch64_ssubl2<mode>"
2155 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2156 (match_operand:VQW 1 "register_operand" "w")
2157 (match_operand:VQW 2 "register_operand" "w")]
2160 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2161 emit_insn (gen_aarch64_ssubl2<mode>_internal (operands[0], operands[1],
2166 (define_expand "aarch64_usubl2<mode>"
2167 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2168 (match_operand:VQW 1 "register_operand" "w")
2169 (match_operand:VQW 2 "register_operand" "w")]
2172 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2173 emit_insn (gen_aarch64_usubl2<mode>_internal (operands[0], operands[1],
2178 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l<mode>"
2179 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2180 (ADDSUB:<VWIDE> (ANY_EXTEND:<VWIDE>
2181 (match_operand:VDW 1 "register_operand" "w"))
2183 (match_operand:VDW 2 "register_operand" "w"))))]
2185 "<ANY_EXTEND:su><ADDSUB:optab>l %0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
2186 [(set_attr "simd_type" "simd_addl")
2187 (set_attr "simd_mode" "<MODE>")]
2190 ;; <su><addsub>w<q>.
2192 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>w<mode>"
2193 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2194 (ADDSUB:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "w")
2196 (match_operand:VDW 2 "register_operand" "w"))))]
2198 "<ANY_EXTEND:su><ADDSUB:optab>w\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
2199 [(set_attr "simd_type" "simd_addl")
2200 (set_attr "simd_mode" "<MODE>")]
2203 (define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>w2<mode>_internal"
2204 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2205 (ADDSUB:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "w")
2208 (match_operand:VQW 2 "register_operand" "w")
2209 (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))))]
2211 "<ANY_EXTEND:su><ADDSUB:optab>w2\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
2212 [(set_attr "simd_type" "simd_addl")
2213 (set_attr "simd_mode" "<MODE>")]
2216 (define_expand "aarch64_saddw2<mode>"
2217 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2218 (match_operand:<VWIDE> 1 "register_operand" "w")
2219 (match_operand:VQW 2 "register_operand" "w")]
2222 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2223 emit_insn (gen_aarch64_saddw2<mode>_internal (operands[0], operands[1],
2228 (define_expand "aarch64_uaddw2<mode>"
2229 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2230 (match_operand:<VWIDE> 1 "register_operand" "w")
2231 (match_operand:VQW 2 "register_operand" "w")]
2234 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2235 emit_insn (gen_aarch64_uaddw2<mode>_internal (operands[0], operands[1],
2241 (define_expand "aarch64_ssubw2<mode>"
2242 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2243 (match_operand:<VWIDE> 1 "register_operand" "w")
2244 (match_operand:VQW 2 "register_operand" "w")]
2247 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2248 emit_insn (gen_aarch64_ssubw2<mode>_internal (operands[0], operands[1],
2253 (define_expand "aarch64_usubw2<mode>"
2254 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2255 (match_operand:<VWIDE> 1 "register_operand" "w")
2256 (match_operand:VQW 2 "register_operand" "w")]
2259 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2260 emit_insn (gen_aarch64_usubw2<mode>_internal (operands[0], operands[1],
2265 ;; <su><r>h<addsub>.
2267 (define_insn "aarch64_<sur>h<addsub><mode>"
2268 [(set (match_operand:VQ_S 0 "register_operand" "=w")
2269 (unspec:VQ_S [(match_operand:VQ_S 1 "register_operand" "w")
2270 (match_operand:VQ_S 2 "register_operand" "w")]
2273 "<sur>h<addsub>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
2274 [(set_attr "simd_type" "simd_add")
2275 (set_attr "simd_mode" "<MODE>")]
2278 ;; <r><addsub>hn<q>.
2280 (define_insn "aarch64_<sur><addsub>hn<mode>"
2281 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
2282 (unspec:<VNARROWQ> [(match_operand:VQN 1 "register_operand" "w")
2283 (match_operand:VQN 2 "register_operand" "w")]
2286 "<sur><addsub>hn\\t%0.<Vntype>, %1.<Vtype>, %2.<Vtype>"
2287 [(set_attr "simd_type" "simd_addn")
2288 (set_attr "simd_mode" "<MODE>")]
2291 (define_insn "aarch64_<sur><addsub>hn2<mode>"
2292 [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=w")
2293 (unspec:<VNARROWQ2> [(match_operand:<VNARROWQ> 1 "register_operand" "0")
2294 (match_operand:VQN 2 "register_operand" "w")
2295 (match_operand:VQN 3 "register_operand" "w")]
2298 "<sur><addsub>hn2\\t%0.<V2ntype>, %2.<Vtype>, %3.<Vtype>"
2299 [(set_attr "simd_type" "simd_addn2")
2300 (set_attr "simd_mode" "<MODE>")]
2305 (define_insn "aarch64_pmul<mode>"
2306 [(set (match_operand:VB 0 "register_operand" "=w")
2307 (unspec:VB [(match_operand:VB 1 "register_operand" "w")
2308 (match_operand:VB 2 "register_operand" "w")]
2311 "pmul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
2312 [(set_attr "simd_type" "simd_mul")
2313 (set_attr "simd_mode" "<MODE>")]
2318 (define_insn "aarch64_<su_optab><optab><mode>"
2319 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
2320 (BINQOPS:VSDQ_I (match_operand:VSDQ_I 1 "register_operand" "w")
2321 (match_operand:VSDQ_I 2 "register_operand" "w")))]
2323 "<su_optab><optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
2324 [(set_attr "simd_type" "simd_add")
2325 (set_attr "simd_mode" "<MODE>")]
2328 ;; suqadd and usqadd
2330 (define_insn "aarch64_<sur>qadd<mode>"
2331 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
2332 (unspec:VSDQ_I [(match_operand:VSDQ_I 1 "register_operand" "0")
2333 (match_operand:VSDQ_I 2 "register_operand" "w")]
2336 "<sur>qadd\\t%<v>0<Vmtype>, %<v>2<Vmtype>"
2337 [(set_attr "simd_type" "simd_sat_add")
2338 (set_attr "simd_mode" "<MODE>")]
2343 (define_insn "aarch64_sqmovun<mode>"
2344 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
2345 (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")]
2348 "sqxtun\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
2349 [(set_attr "simd_type" "simd_sat_shiftn_imm")
2350 (set_attr "simd_mode" "<MODE>")]
2353 ;; sqmovn and uqmovn
2355 (define_insn "aarch64_<sur>qmovn<mode>"
2356 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
2357 (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")]
2360 "<sur>qxtn\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
2361 [(set_attr "simd_type" "simd_sat_shiftn_imm")
2362 (set_attr "simd_mode" "<MODE>")]
2367 (define_insn "aarch64_s<optab><mode>"
2368 [(set (match_operand:VSDQ_I_BHSI 0 "register_operand" "=w")
2370 (match_operand:VSDQ_I_BHSI 1 "register_operand" "w")))]
2372 "s<optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>"
2373 [(set_attr "simd_type" "simd_sat_negabs")
2374 (set_attr "simd_mode" "<MODE>")]
2379 (define_insn "aarch64_sq<r>dmulh<mode>"
2380 [(set (match_operand:VSDQ_HSI 0 "register_operand" "=w")
2382 [(match_operand:VSDQ_HSI 1 "register_operand" "w")
2383 (match_operand:VSDQ_HSI 2 "register_operand" "w")]
2386 "sq<r>dmulh\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
2387 [(set_attr "simd_type" "simd_sat_mul")
2388 (set_attr "simd_mode" "<MODE>")]
2393 (define_insn "aarch64_sq<r>dmulh_lane<mode>"
2394 [(set (match_operand:VDQHS 0 "register_operand" "=w")
2396 [(match_operand:VDQHS 1 "register_operand" "w")
2398 (match_operand:<VCOND> 2 "register_operand" "<vwx>")
2399 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
2403 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
2404 return \"sq<r>dmulh\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]\";"
2405 [(set_attr "simd_type" "simd_sat_mul")
2406 (set_attr "simd_mode" "<MODE>")]
2409 (define_insn "aarch64_sq<r>dmulh_laneq<mode>"
2410 [(set (match_operand:VDQHS 0 "register_operand" "=w")
2412 [(match_operand:VDQHS 1 "register_operand" "w")
2414 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
2415 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
2419 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
2420 return \"sq<r>dmulh\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]\";"
2421 [(set_attr "simd_type" "simd_sat_mul")
2422 (set_attr "simd_mode" "<MODE>")]
2425 (define_insn "aarch64_sq<r>dmulh_lane<mode>"
2426 [(set (match_operand:SD_HSI 0 "register_operand" "=w")
2428 [(match_operand:SD_HSI 1 "register_operand" "w")
2430 (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
2431 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
2435 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
2436 return \"sq<r>dmulh\\t%<v>0, %<v>1, %2.<v>[%3]\";"
2437 [(set_attr "simd_type" "simd_sat_mul")
2438 (set_attr "simd_mode" "<MODE>")]
2443 (define_insn "aarch64_sqdml<SBINQOPS:as>l<mode>"
2444 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2446 (match_operand:<VWIDE> 1 "register_operand" "0")
2449 (sign_extend:<VWIDE>
2450 (match_operand:VSD_HSI 2 "register_operand" "w"))
2451 (sign_extend:<VWIDE>
2452 (match_operand:VSD_HSI 3 "register_operand" "w")))
2455 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %<v>3<Vmtype>"
2456 [(set_attr "simd_type" "simd_sat_mlal")
2457 (set_attr "simd_mode" "<MODE>")]
2462 (define_insn "aarch64_sqdml<SBINQOPS:as>l_lane<mode>_internal"
2463 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2465 (match_operand:<VWIDE> 1 "register_operand" "0")
2468 (sign_extend:<VWIDE>
2469 (match_operand:VD_HSI 2 "register_operand" "w"))
2470 (sign_extend:<VWIDE>
2471 (vec_duplicate:VD_HSI
2473 (match_operand:<VCON> 3 "register_operand" "<vwx>")
2474 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
2478 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"
2479 [(set_attr "simd_type" "simd_sat_mlal")
2480 (set_attr "simd_mode" "<MODE>")]
2483 (define_insn "aarch64_sqdml<SBINQOPS:as>l_lane<mode>_internal"
2484 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2486 (match_operand:<VWIDE> 1 "register_operand" "0")
2489 (sign_extend:<VWIDE>
2490 (match_operand:SD_HSI 2 "register_operand" "w"))
2491 (sign_extend:<VWIDE>
2493 (match_operand:<VCON> 3 "register_operand" "<vwx>")
2494 (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
2498 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"
2499 [(set_attr "simd_type" "simd_sat_mlal")
2500 (set_attr "simd_mode" "<MODE>")]
2503 (define_expand "aarch64_sqdmlal_lane<mode>"
2504 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2505 (match_operand:<VWIDE> 1 "register_operand" "0")
2506 (match_operand:VSD_HSI 2 "register_operand" "w")
2507 (match_operand:<VCON> 3 "register_operand" "<vwx>")
2508 (match_operand:SI 4 "immediate_operand" "i")]
2511 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCON>mode) / 2);
2512 emit_insn (gen_aarch64_sqdmlal_lane<mode>_internal (operands[0], operands[1],
2513 operands[2], operands[3],
2518 (define_expand "aarch64_sqdmlal_laneq<mode>"
2519 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2520 (match_operand:<VWIDE> 1 "register_operand" "0")
2521 (match_operand:VSD_HSI 2 "register_operand" "w")
2522 (match_operand:<VCON> 3 "register_operand" "<vwx>")
2523 (match_operand:SI 4 "immediate_operand" "i")]
2526 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCON>mode));
2527 emit_insn (gen_aarch64_sqdmlal_lane<mode>_internal (operands[0], operands[1],
2528 operands[2], operands[3],
2533 (define_expand "aarch64_sqdmlsl_lane<mode>"
2534 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2535 (match_operand:<VWIDE> 1 "register_operand" "0")
2536 (match_operand:VSD_HSI 2 "register_operand" "w")
2537 (match_operand:<VCON> 3 "register_operand" "<vwx>")
2538 (match_operand:SI 4 "immediate_operand" "i")]
2541 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCON>mode) / 2);
2542 emit_insn (gen_aarch64_sqdmlsl_lane<mode>_internal (operands[0], operands[1],
2543 operands[2], operands[3],
2548 (define_expand "aarch64_sqdmlsl_laneq<mode>"
2549 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2550 (match_operand:<VWIDE> 1 "register_operand" "0")
2551 (match_operand:VSD_HSI 2 "register_operand" "w")
2552 (match_operand:<VCON> 3 "register_operand" "<vwx>")
2553 (match_operand:SI 4 "immediate_operand" "i")]
2556 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCON>mode));
2557 emit_insn (gen_aarch64_sqdmlsl_lane<mode>_internal (operands[0], operands[1],
2558 operands[2], operands[3],
2565 (define_insn "aarch64_sqdml<SBINQOPS:as>l_n<mode>"
2566 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2568 (match_operand:<VWIDE> 1 "register_operand" "0")
2571 (sign_extend:<VWIDE>
2572 (match_operand:VD_HSI 2 "register_operand" "w"))
2573 (sign_extend:<VWIDE>
2574 (vec_duplicate:VD_HSI
2575 (match_operand:<VEL> 3 "register_operand" "w"))))
2578 "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
2579 [(set_attr "simd_type" "simd_sat_mlal")
2580 (set_attr "simd_mode" "<MODE>")]
2585 (define_insn "aarch64_sqdml<SBINQOPS:as>l2<mode>_internal"
2586 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2588 (match_operand:<VWIDE> 1 "register_operand" "0")
2591 (sign_extend:<VWIDE>
2593 (match_operand:VQ_HSI 2 "register_operand" "w")
2594 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
2595 (sign_extend:<VWIDE>
2597 (match_operand:VQ_HSI 3 "register_operand" "w")
2601 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %<v>3<Vmtype>"
2602 [(set_attr "simd_type" "simd_sat_mlal")
2603 (set_attr "simd_mode" "<MODE>")]
2606 (define_expand "aarch64_sqdmlal2<mode>"
2607 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2608 (match_operand:<VWIDE> 1 "register_operand" "w")
2609 (match_operand:VQ_HSI 2 "register_operand" "w")
2610 (match_operand:VQ_HSI 3 "register_operand" "w")]
2613 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2614 emit_insn (gen_aarch64_sqdmlal2<mode>_internal (operands[0], operands[1],
2615 operands[2], operands[3], p));
2619 (define_expand "aarch64_sqdmlsl2<mode>"
2620 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2621 (match_operand:<VWIDE> 1 "register_operand" "w")
2622 (match_operand:VQ_HSI 2 "register_operand" "w")
2623 (match_operand:VQ_HSI 3 "register_operand" "w")]
2626 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2627 emit_insn (gen_aarch64_sqdmlsl2<mode>_internal (operands[0], operands[1],
2628 operands[2], operands[3], p));
2634 (define_insn "aarch64_sqdml<SBINQOPS:as>l2_lane<mode>_internal"
2635 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2637 (match_operand:<VWIDE> 1 "register_operand" "0")
2640 (sign_extend:<VWIDE>
2642 (match_operand:VQ_HSI 2 "register_operand" "w")
2643 (match_operand:VQ_HSI 5 "vect_par_cnst_hi_half" "")))
2644 (sign_extend:<VWIDE>
2645 (vec_duplicate:<VHALF>
2647 (match_operand:<VCON> 3 "register_operand" "<vwx>")
2648 (parallel [(match_operand:SI 4 "immediate_operand" "i")])
2652 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"
2653 [(set_attr "simd_type" "simd_sat_mlal")
2654 (set_attr "simd_mode" "<MODE>")]
2657 (define_expand "aarch64_sqdmlal2_lane<mode>"
2658 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2659 (match_operand:<VWIDE> 1 "register_operand" "w")
2660 (match_operand:VQ_HSI 2 "register_operand" "w")
2661 (match_operand:<VCON> 3 "register_operand" "<vwx>")
2662 (match_operand:SI 4 "immediate_operand" "i")]
2665 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2666 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode) / 2);
2667 emit_insn (gen_aarch64_sqdmlal2_lane<mode>_internal (operands[0], operands[1],
2668 operands[2], operands[3],
2673 (define_expand "aarch64_sqdmlal2_laneq<mode>"
2674 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2675 (match_operand:<VWIDE> 1 "register_operand" "w")
2676 (match_operand:VQ_HSI 2 "register_operand" "w")
2677 (match_operand:<VCON> 3 "register_operand" "<vwx>")
2678 (match_operand:SI 4 "immediate_operand" "i")]
2681 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2682 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
2683 emit_insn (gen_aarch64_sqdmlal2_lane<mode>_internal (operands[0], operands[1],
2684 operands[2], operands[3],
2689 (define_expand "aarch64_sqdmlsl2_lane<mode>"
2690 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2691 (match_operand:<VWIDE> 1 "register_operand" "w")
2692 (match_operand:VQ_HSI 2 "register_operand" "w")
2693 (match_operand:<VCON> 3 "register_operand" "<vwx>")
2694 (match_operand:SI 4 "immediate_operand" "i")]
2697 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2698 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode) / 2);
2699 emit_insn (gen_aarch64_sqdmlsl2_lane<mode>_internal (operands[0], operands[1],
2700 operands[2], operands[3],
2705 (define_expand "aarch64_sqdmlsl2_laneq<mode>"
2706 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2707 (match_operand:<VWIDE> 1 "register_operand" "w")
2708 (match_operand:VQ_HSI 2 "register_operand" "w")
2709 (match_operand:<VCON> 3 "register_operand" "<vwx>")
2710 (match_operand:SI 4 "immediate_operand" "i")]
2713 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2714 aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
2715 emit_insn (gen_aarch64_sqdmlsl2_lane<mode>_internal (operands[0], operands[1],
2716 operands[2], operands[3],
2721 (define_insn "aarch64_sqdml<SBINQOPS:as>l2_n<mode>_internal"
2722 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2724 (match_operand:<VWIDE> 1 "register_operand" "0")
2727 (sign_extend:<VWIDE>
2729 (match_operand:VQ_HSI 2 "register_operand" "w")
2730 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
2731 (sign_extend:<VWIDE>
2732 (vec_duplicate:<VHALF>
2733 (match_operand:<VEL> 3 "register_operand" "w"))))
2736 "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
2737 [(set_attr "simd_type" "simd_sat_mlal")
2738 (set_attr "simd_mode" "<MODE>")]
2741 (define_expand "aarch64_sqdmlal2_n<mode>"
2742 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2743 (match_operand:<VWIDE> 1 "register_operand" "w")
2744 (match_operand:VQ_HSI 2 "register_operand" "w")
2745 (match_operand:<VEL> 3 "register_operand" "w")]
2748 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2749 emit_insn (gen_aarch64_sqdmlal2_n<mode>_internal (operands[0], operands[1],
2750 operands[2], operands[3],
2755 (define_expand "aarch64_sqdmlsl2_n<mode>"
2756 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2757 (match_operand:<VWIDE> 1 "register_operand" "w")
2758 (match_operand:VQ_HSI 2 "register_operand" "w")
2759 (match_operand:<VEL> 3 "register_operand" "w")]
2762 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2763 emit_insn (gen_aarch64_sqdmlsl2_n<mode>_internal (operands[0], operands[1],
2764 operands[2], operands[3],
2771 (define_insn "aarch64_sqdmull<mode>"
2772 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2775 (sign_extend:<VWIDE>
2776 (match_operand:VSD_HSI 1 "register_operand" "w"))
2777 (sign_extend:<VWIDE>
2778 (match_operand:VSD_HSI 2 "register_operand" "w")))
2781 "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
2782 [(set_attr "simd_type" "simd_sat_mul")
2783 (set_attr "simd_mode" "<MODE>")]
2788 (define_insn "aarch64_sqdmull_lane<mode>_internal"
2789 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2792 (sign_extend:<VWIDE>
2793 (match_operand:VD_HSI 1 "register_operand" "w"))
2794 (sign_extend:<VWIDE>
2795 (vec_duplicate:VD_HSI
2797 (match_operand:<VCON> 2 "register_operand" "<vwx>")
2798 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
2802 "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]"
2803 [(set_attr "simd_type" "simd_sat_mul")
2804 (set_attr "simd_mode" "<MODE>")]
2807 (define_insn "aarch64_sqdmull_lane<mode>_internal"
2808 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2811 (sign_extend:<VWIDE>
2812 (match_operand:SD_HSI 1 "register_operand" "w"))
2813 (sign_extend:<VWIDE>
2815 (match_operand:<VCON> 2 "register_operand" "<vwx>")
2816 (parallel [(match_operand:SI 3 "immediate_operand" "i")]))
2820 "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]"
2821 [(set_attr "simd_type" "simd_sat_mul")
2822 (set_attr "simd_mode" "<MODE>")]
2825 (define_expand "aarch64_sqdmull_lane<mode>"
2826 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2827 (match_operand:VSD_HSI 1 "register_operand" "w")
2828 (match_operand:<VCON> 2 "register_operand" "<vwx>")
2829 (match_operand:SI 3 "immediate_operand" "i")]
2832 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCON>mode) / 2);
2833 emit_insn (gen_aarch64_sqdmull_lane<mode>_internal (operands[0], operands[1],
2834 operands[2], operands[3]));
2838 (define_expand "aarch64_sqdmull_laneq<mode>"
2839 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2840 (match_operand:VD_HSI 1 "register_operand" "w")
2841 (match_operand:<VCON> 2 "register_operand" "<vwx>")
2842 (match_operand:SI 3 "immediate_operand" "i")]
2845 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCON>mode));
2846 emit_insn (gen_aarch64_sqdmull_lane<mode>_internal
2847 (operands[0], operands[1], operands[2], operands[3]));
2853 (define_insn "aarch64_sqdmull_n<mode>"
2854 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2857 (sign_extend:<VWIDE>
2858 (match_operand:VD_HSI 1 "register_operand" "w"))
2859 (sign_extend:<VWIDE>
2860 (vec_duplicate:VD_HSI
2861 (match_operand:<VEL> 2 "register_operand" "w")))
2865 "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[0]"
2866 [(set_attr "simd_type" "simd_sat_mul")
2867 (set_attr "simd_mode" "<MODE>")]
2874 (define_insn "aarch64_sqdmull2<mode>_internal"
2875 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2878 (sign_extend:<VWIDE>
2880 (match_operand:VQ_HSI 1 "register_operand" "w")
2881 (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
2882 (sign_extend:<VWIDE>
2884 (match_operand:VQ_HSI 2 "register_operand" "w")
2889 "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
2890 [(set_attr "simd_type" "simd_sat_mul")
2891 (set_attr "simd_mode" "<MODE>")]
2894 (define_expand "aarch64_sqdmull2<mode>"
2895 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2896 (match_operand:VQ_HSI 1 "register_operand" "w")
2897 (match_operand:<VCON> 2 "register_operand" "w")]
2900 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2901 emit_insn (gen_aarch64_sqdmull2<mode>_internal (operands[0], operands[1],
2908 (define_insn "aarch64_sqdmull2_lane<mode>_internal"
2909 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2912 (sign_extend:<VWIDE>
2914 (match_operand:VQ_HSI 1 "register_operand" "w")
2915 (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
2916 (sign_extend:<VWIDE>
2917 (vec_duplicate:<VHALF>
2919 (match_operand:<VCON> 2 "register_operand" "<vwx>")
2920 (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
2924 "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]"
2925 [(set_attr "simd_type" "simd_sat_mul")
2926 (set_attr "simd_mode" "<MODE>")]
2929 (define_expand "aarch64_sqdmull2_lane<mode>"
2930 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2931 (match_operand:VQ_HSI 1 "register_operand" "w")
2932 (match_operand:<VCON> 2 "register_operand" "<vwx>")
2933 (match_operand:SI 3 "immediate_operand" "i")]
2936 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2937 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode) / 2);
2938 emit_insn (gen_aarch64_sqdmull2_lane<mode>_internal (operands[0], operands[1],
2939 operands[2], operands[3],
2944 (define_expand "aarch64_sqdmull2_laneq<mode>"
2945 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2946 (match_operand:VQ_HSI 1 "register_operand" "w")
2947 (match_operand:<VCON> 2 "register_operand" "<vwx>")
2948 (match_operand:SI 3 "immediate_operand" "i")]
2951 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2952 aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
2953 emit_insn (gen_aarch64_sqdmull2_lane<mode>_internal (operands[0], operands[1],
2954 operands[2], operands[3],
2961 (define_insn "aarch64_sqdmull2_n<mode>_internal"
2962 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2965 (sign_extend:<VWIDE>
2967 (match_operand:VQ_HSI 1 "register_operand" "w")
2968 (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
2969 (sign_extend:<VWIDE>
2970 (vec_duplicate:<VHALF>
2971 (match_operand:<VEL> 2 "register_operand" "w")))
2975 "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[0]"
2976 [(set_attr "simd_type" "simd_sat_mul")
2977 (set_attr "simd_mode" "<MODE>")]
2980 (define_expand "aarch64_sqdmull2_n<mode>"
2981 [(match_operand:<VWIDE> 0 "register_operand" "=w")
2982 (match_operand:VQ_HSI 1 "register_operand" "w")
2983 (match_operand:<VEL> 2 "register_operand" "w")]
2986 rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
2987 emit_insn (gen_aarch64_sqdmull2_n<mode>_internal (operands[0], operands[1],
2994 (define_insn "aarch64_<sur>shl<mode>"
2995 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
2997 [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
2998 (match_operand:VSDQ_I_DI 2 "register_operand" "w")]
3001 "<sur>shl\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>";
3002 [(set_attr "simd_type" "simd_shift")
3003 (set_attr "simd_mode" "<MODE>")]
3009 (define_insn "aarch64_<sur>q<r>shl<mode>"
3010 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
3012 [(match_operand:VSDQ_I 1 "register_operand" "w")
3013 (match_operand:VSDQ_I 2 "register_operand" "w")]
3016 "<sur>q<r>shl\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>";
3017 [(set_attr "simd_type" "simd_sat_shift")
3018 (set_attr "simd_mode" "<MODE>")]
3023 (define_insn "aarch64_<sur>shll_n<mode>"
3024 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3025 (unspec:<VWIDE> [(match_operand:VDW 1 "register_operand" "w")
3026 (match_operand:SI 2 "immediate_operand" "i")]
3030 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3031 aarch64_simd_const_bounds (operands[2], 0, bit_width + 1);
3032 if (INTVAL (operands[2]) == bit_width)
3034 return \"shll\\t%0.<Vwtype>, %1.<Vtype>, %2\";
3037 return \"<sur>shll\\t%0.<Vwtype>, %1.<Vtype>, %2\";
3039 [(set_attr "simd_type" "simd_shift_imm")
3040 (set_attr "simd_mode" "<MODE>")]
3045 (define_insn "aarch64_<sur>shll2_n<mode>"
3046 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
3047 (unspec:<VWIDE> [(match_operand:VQW 1 "register_operand" "w")
3048 (match_operand:SI 2 "immediate_operand" "i")]
3052 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3053 aarch64_simd_const_bounds (operands[2], 0, bit_width + 1);
3054 if (INTVAL (operands[2]) == bit_width)
3056 return \"shll2\\t%0.<Vwtype>, %1.<Vtype>, %2\";
3059 return \"<sur>shll2\\t%0.<Vwtype>, %1.<Vtype>, %2\";
3061 [(set_attr "simd_type" "simd_shift_imm")
3062 (set_attr "simd_mode" "<MODE>")]
3067 (define_insn "aarch64_<sur>shr_n<mode>"
3068 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
3069 (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
3070 (match_operand:SI 2 "immediate_operand" "i")]
3074 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3075 aarch64_simd_const_bounds (operands[2], 1, bit_width + 1);
3076 return \"<sur>shr\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2\";"
3077 [(set_attr "simd_type" "simd_shift_imm")
3078 (set_attr "simd_mode" "<MODE>")]
3083 (define_insn "aarch64_<sur>sra_n<mode>"
3084 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
3085 (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "0")
3086 (match_operand:VSDQ_I_DI 2 "register_operand" "w")
3087 (match_operand:SI 3 "immediate_operand" "i")]
3091 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3092 aarch64_simd_const_bounds (operands[3], 1, bit_width + 1);
3093 return \"<sur>sra\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3\";"
3094 [(set_attr "simd_type" "simd_shift_imm_acc")
3095 (set_attr "simd_mode" "<MODE>")]
3100 (define_insn "aarch64_<sur>s<lr>i_n<mode>"
3101 [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
3102 (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "0")
3103 (match_operand:VSDQ_I_DI 2 "register_operand" "w")
3104 (match_operand:SI 3 "immediate_operand" "i")]
3108 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3109 aarch64_simd_const_bounds (operands[3], 1 - <VSLRI:offsetlr>,
3110 bit_width - <VSLRI:offsetlr> + 1);
3111 return \"s<lr>i\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3\";"
3112 [(set_attr "simd_type" "simd_shift_imm")
3113 (set_attr "simd_mode" "<MODE>")]
3118 (define_insn "aarch64_<sur>qshl<u>_n<mode>"
3119 [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
3120 (unspec:VSDQ_I [(match_operand:VSDQ_I 1 "register_operand" "w")
3121 (match_operand:SI 2 "immediate_operand" "i")]
3125 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3126 aarch64_simd_const_bounds (operands[2], 0, bit_width);
3127 return \"<sur>qshl<u>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2\";"
3128 [(set_attr "simd_type" "simd_sat_shift_imm")
3129 (set_attr "simd_mode" "<MODE>")]
3135 (define_insn "aarch64_<sur>q<r>shr<u>n_n<mode>"
3136 [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
3137 (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")
3138 (match_operand:SI 2 "immediate_operand" "i")]
3142 int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
3143 aarch64_simd_const_bounds (operands[2], 1, bit_width + 1);
3144 return \"<sur>q<r>shr<u>n\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>, %2\";"
3145 [(set_attr "simd_type" "simd_sat_shiftn_imm")
3146 (set_attr "simd_mode" "<MODE>")]
3150 ;; cm(eq|ge|le|lt|gt)
3152 (define_insn "aarch64_cm<cmp><mode>"
3153 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w,w")
3154 (unspec:<V_cmp_result>
3155 [(match_operand:VSDQ_I_DI 1 "register_operand" "w,w")
3156 (match_operand:VSDQ_I_DI 2 "aarch64_simd_reg_or_zero" "w,Z")]
3160 cm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>
3161 cm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, #0"
3162 [(set_attr "simd_type" "simd_cmp")
3163 (set_attr "simd_mode" "<MODE>")]
3168 (define_insn "aarch64_cm<cmp><mode>"
3169 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w")
3170 (unspec:<V_cmp_result>
3171 [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
3172 (match_operand:VSDQ_I_DI 2 "register_operand" "w")]
3175 "cm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
3176 [(set_attr "simd_type" "simd_cmp")
3177 (set_attr "simd_mode" "<MODE>")]
3180 ;; fcm(eq|ge|le|lt|gt)
3182 (define_insn "aarch64_cm<cmp><mode>"
3183 [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w,w")
3184 (unspec:<V_cmp_result>
3185 [(match_operand:VDQF 1 "register_operand" "w,w")
3186 (match_operand:VDQF 2 "aarch64_simd_reg_or_zero" "w,Dz")]
3190 fcm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>
3191 fcm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, 0"
3192 [(set_attr "simd_type" "simd_fcmp")
3193 (set_attr "simd_mode" "<MODE>")]
3198 (define_insn "aarch64_addp<mode>"
3199 [(set (match_operand:VD_BHSI 0 "register_operand" "=w")
3201 [(match_operand:VD_BHSI 1 "register_operand" "w")
3202 (match_operand:VD_BHSI 2 "register_operand" "w")]
3205 "addp\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
3206 [(set_attr "simd_type" "simd_add")
3207 (set_attr "simd_mode" "<MODE>")]
3210 (define_insn "aarch64_addpdi"
3211 [(set (match_operand:DI 0 "register_operand" "=w")
3213 [(match_operand:V2DI 1 "register_operand" "w")]
3217 [(set_attr "simd_type" "simd_add")
3218 (set_attr "simd_mode" "DI")]
3221 (define_insn "aarch64_<fmaxmin><mode>"
3222 [(set (match_operand:VDQF 0 "register_operand" "=w")
3223 (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")
3224 (match_operand:VDQF 2 "register_operand" "w")]
3227 "<fmaxmin>\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
3228 [(set_attr "simd_type" "simd_fminmax")
3229 (set_attr "simd_mode" "<MODE>")]
3234 (define_insn "sqrt<mode>2"
3235 [(set (match_operand:VDQF 0 "register_operand" "=w")
3236 (sqrt:VDQF (match_operand:VDQF 1 "register_operand" "w")))]
3238 "fsqrt\\t%0.<Vtype>, %1.<Vtype>"
3239 [(set_attr "simd_type" "simd_fsqrt")
3240 (set_attr "simd_mode" "<MODE>")]
3243 ;; Patterns for vector struct loads and stores.
3245 (define_insn "vec_load_lanesoi<mode>"
3246 [(set (match_operand:OI 0 "register_operand" "=w")
3247 (unspec:OI [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")
3248 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3251 "ld2\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
3252 [(set_attr "simd_type" "simd_load2")
3253 (set_attr "simd_mode" "<MODE>")])
3255 (define_insn "vec_store_lanesoi<mode>"
3256 [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
3257 (unspec:OI [(match_operand:OI 1 "register_operand" "w")
3258 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3261 "st2\\t{%S1.<Vtype> - %T1.<Vtype>}, %0"
3262 [(set_attr "simd_type" "simd_store2")
3263 (set_attr "simd_mode" "<MODE>")])
3265 (define_insn "vec_load_lanesci<mode>"
3266 [(set (match_operand:CI 0 "register_operand" "=w")
3267 (unspec:CI [(match_operand:CI 1 "aarch64_simd_struct_operand" "Utv")
3268 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3271 "ld3\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
3272 [(set_attr "simd_type" "simd_load3")
3273 (set_attr "simd_mode" "<MODE>")])
3275 (define_insn "vec_store_lanesci<mode>"
3276 [(set (match_operand:CI 0 "aarch64_simd_struct_operand" "=Utv")
3277 (unspec:CI [(match_operand:CI 1 "register_operand" "w")
3278 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3281 "st3\\t{%S1.<Vtype> - %U1.<Vtype>}, %0"
3282 [(set_attr "simd_type" "simd_store3")
3283 (set_attr "simd_mode" "<MODE>")])
3285 (define_insn "vec_load_lanesxi<mode>"
3286 [(set (match_operand:XI 0 "register_operand" "=w")
3287 (unspec:XI [(match_operand:XI 1 "aarch64_simd_struct_operand" "Utv")
3288 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3291 "ld4\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
3292 [(set_attr "simd_type" "simd_load4")
3293 (set_attr "simd_mode" "<MODE>")])
3295 (define_insn "vec_store_lanesxi<mode>"
3296 [(set (match_operand:XI 0 "aarch64_simd_struct_operand" "=Utv")
3297 (unspec:XI [(match_operand:XI 1 "register_operand" "w")
3298 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3301 "st4\\t{%S1.<Vtype> - %V1.<Vtype>}, %0"
3302 [(set_attr "simd_type" "simd_store4")
3303 (set_attr "simd_mode" "<MODE>")])
3305 ;; Reload patterns for AdvSIMD register list operands.
3307 (define_expand "mov<mode>"
3308 [(set (match_operand:VSTRUCT 0 "aarch64_simd_nonimmediate_operand" "")
3309 (match_operand:VSTRUCT 1 "aarch64_simd_general_operand" ""))]
3312 if (can_create_pseudo_p ())
3314 if (GET_CODE (operands[0]) != REG)
3315 operands[1] = force_reg (<MODE>mode, operands[1]);
3319 (define_insn "*aarch64_mov<mode>"
3320 [(set (match_operand:VSTRUCT 0 "aarch64_simd_nonimmediate_operand" "=w,Utv,w")
3321 (match_operand:VSTRUCT 1 "aarch64_simd_general_operand" " w,w,Utv"))]
3323 && (register_operand (operands[0], <MODE>mode)
3324 || register_operand (operands[1], <MODE>mode))"
3327 switch (which_alternative)
3330 case 1: return "st1\\t{%S1.16b - %<Vendreg>1.16b}, %0";
3331 case 2: return "ld1\\t{%S0.16b - %<Vendreg>0.16b}, %1";
3332 default: gcc_unreachable ();
3335 [(set_attr "simd_type" "simd_move,simd_store<nregs>,simd_load<nregs>")
3336 (set (attr "length") (symbol_ref "aarch64_simd_attr_length_move (insn)"))
3337 (set_attr "simd_mode" "<MODE>")])
3340 [(set (match_operand:OI 0 "register_operand" "")
3341 (match_operand:OI 1 "register_operand" ""))]
3342 "TARGET_SIMD && reload_completed"
3343 [(set (match_dup 0) (match_dup 1))
3344 (set (match_dup 2) (match_dup 3))]
3346 int rdest = REGNO (operands[0]);
3347 int rsrc = REGNO (operands[1]);
3348 rtx dest[2], src[2];
3350 dest[0] = gen_rtx_REG (TFmode, rdest);
3351 src[0] = gen_rtx_REG (TFmode, rsrc);
3352 dest[1] = gen_rtx_REG (TFmode, rdest + 1);
3353 src[1] = gen_rtx_REG (TFmode, rsrc + 1);
3355 aarch64_simd_disambiguate_copy (operands, dest, src, 2);
3359 [(set (match_operand:CI 0 "register_operand" "")
3360 (match_operand:CI 1 "register_operand" ""))]
3361 "TARGET_SIMD && reload_completed"
3362 [(set (match_dup 0) (match_dup 1))
3363 (set (match_dup 2) (match_dup 3))
3364 (set (match_dup 4) (match_dup 5))]
3366 int rdest = REGNO (operands[0]);
3367 int rsrc = REGNO (operands[1]);
3368 rtx dest[3], src[3];
3370 dest[0] = gen_rtx_REG (TFmode, rdest);
3371 src[0] = gen_rtx_REG (TFmode, rsrc);
3372 dest[1] = gen_rtx_REG (TFmode, rdest + 1);
3373 src[1] = gen_rtx_REG (TFmode, rsrc + 1);
3374 dest[2] = gen_rtx_REG (TFmode, rdest + 2);
3375 src[2] = gen_rtx_REG (TFmode, rsrc + 2);
3377 aarch64_simd_disambiguate_copy (operands, dest, src, 3);
3381 [(set (match_operand:XI 0 "register_operand" "")
3382 (match_operand:XI 1 "register_operand" ""))]
3383 "TARGET_SIMD && reload_completed"
3384 [(set (match_dup 0) (match_dup 1))
3385 (set (match_dup 2) (match_dup 3))
3386 (set (match_dup 4) (match_dup 5))
3387 (set (match_dup 6) (match_dup 7))]
3389 int rdest = REGNO (operands[0]);
3390 int rsrc = REGNO (operands[1]);
3391 rtx dest[4], src[4];
3393 dest[0] = gen_rtx_REG (TFmode, rdest);
3394 src[0] = gen_rtx_REG (TFmode, rsrc);
3395 dest[1] = gen_rtx_REG (TFmode, rdest + 1);
3396 src[1] = gen_rtx_REG (TFmode, rsrc + 1);
3397 dest[2] = gen_rtx_REG (TFmode, rdest + 2);
3398 src[2] = gen_rtx_REG (TFmode, rsrc + 2);
3399 dest[3] = gen_rtx_REG (TFmode, rdest + 3);
3400 src[3] = gen_rtx_REG (TFmode, rsrc + 3);
3402 aarch64_simd_disambiguate_copy (operands, dest, src, 4);
3405 (define_insn "aarch64_ld2<mode>_dreg"
3406 [(set (match_operand:OI 0 "register_operand" "=w")
3410 (unspec:VD [(match_operand:TI 1 "aarch64_simd_struct_operand" "Utv")]
3412 (vec_duplicate:VD (const_int 0)))
3414 (unspec:VD [(match_dup 1)]
3416 (vec_duplicate:VD (const_int 0)))) 0))]
3418 "ld2\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
3419 [(set_attr "simd_type" "simd_load2")
3420 (set_attr "simd_mode" "<MODE>")])
3422 (define_insn "aarch64_ld2<mode>_dreg"
3423 [(set (match_operand:OI 0 "register_operand" "=w")
3427 (unspec:DX [(match_operand:TI 1 "aarch64_simd_struct_operand" "Utv")]
3431 (unspec:DX [(match_dup 1)]
3433 (const_int 0))) 0))]
3435 "ld1\\t{%S0.1d - %T0.1d}, %1"
3436 [(set_attr "simd_type" "simd_load2")
3437 (set_attr "simd_mode" "<MODE>")])
3439 (define_insn "aarch64_ld3<mode>_dreg"
3440 [(set (match_operand:CI 0 "register_operand" "=w")
3445 (unspec:VD [(match_operand:EI 1 "aarch64_simd_struct_operand" "Utv")]
3447 (vec_duplicate:VD (const_int 0)))
3449 (unspec:VD [(match_dup 1)]
3451 (vec_duplicate:VD (const_int 0))))
3453 (unspec:VD [(match_dup 1)]
3455 (vec_duplicate:VD (const_int 0)))) 0))]
3457 "ld3\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
3458 [(set_attr "simd_type" "simd_load3")
3459 (set_attr "simd_mode" "<MODE>")])
3461 (define_insn "aarch64_ld3<mode>_dreg"
3462 [(set (match_operand:CI 0 "register_operand" "=w")
3467 (unspec:DX [(match_operand:EI 1 "aarch64_simd_struct_operand" "Utv")]
3471 (unspec:DX [(match_dup 1)]
3475 (unspec:DX [(match_dup 1)]
3477 (const_int 0))) 0))]
3479 "ld1\\t{%S0.1d - %U0.1d}, %1"
3480 [(set_attr "simd_type" "simd_load3")
3481 (set_attr "simd_mode" "<MODE>")])
3483 (define_insn "aarch64_ld4<mode>_dreg"
3484 [(set (match_operand:XI 0 "register_operand" "=w")
3489 (unspec:VD [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")]
3491 (vec_duplicate:VD (const_int 0)))
3493 (unspec:VD [(match_dup 1)]
3495 (vec_duplicate:VD (const_int 0))))
3498 (unspec:VD [(match_dup 1)]
3500 (vec_duplicate:VD (const_int 0)))
3502 (unspec:VD [(match_dup 1)]
3504 (vec_duplicate:VD (const_int 0))))) 0))]
3506 "ld4\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
3507 [(set_attr "simd_type" "simd_load4")
3508 (set_attr "simd_mode" "<MODE>")])
3510 (define_insn "aarch64_ld4<mode>_dreg"
3511 [(set (match_operand:XI 0 "register_operand" "=w")
3516 (unspec:DX [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")]
3520 (unspec:DX [(match_dup 1)]
3525 (unspec:DX [(match_dup 1)]
3529 (unspec:DX [(match_dup 1)]
3531 (const_int 0)))) 0))]
3533 "ld1\\t{%S0.1d - %V0.1d}, %1"
3534 [(set_attr "simd_type" "simd_load4")
3535 (set_attr "simd_mode" "<MODE>")])
3537 (define_expand "aarch64_ld<VSTRUCT:nregs><VDC:mode>"
3538 [(match_operand:VSTRUCT 0 "register_operand" "=w")
3539 (match_operand:DI 1 "register_operand" "r")
3540 (unspec:VDC [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3543 enum machine_mode mode = <VSTRUCT:VSTRUCT_DREG>mode;
3544 rtx mem = gen_rtx_MEM (mode, operands[1]);
3546 emit_insn (gen_aarch64_ld<VSTRUCT:nregs><VDC:mode>_dreg (operands[0], mem));
3550 (define_expand "aarch64_ld<VSTRUCT:nregs><VQ:mode>"
3551 [(match_operand:VSTRUCT 0 "register_operand" "=w")
3552 (match_operand:DI 1 "register_operand" "r")
3553 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3556 enum machine_mode mode = <VSTRUCT:MODE>mode;
3557 rtx mem = gen_rtx_MEM (mode, operands[1]);
3559 emit_insn (gen_vec_load_lanes<VSTRUCT:mode><VQ:mode> (operands[0], mem));
3563 ;; Expanders for builtins to extract vector registers from large
3564 ;; opaque integer modes.
3568 (define_expand "aarch64_get_dreg<VSTRUCT:mode><VDC:mode>"
3569 [(match_operand:VDC 0 "register_operand" "=w")
3570 (match_operand:VSTRUCT 1 "register_operand" "w")
3571 (match_operand:SI 2 "immediate_operand" "i")]
3574 int part = INTVAL (operands[2]);
3575 rtx temp = gen_reg_rtx (<VDC:VDBL>mode);
3576 int offset = part * 16;
3578 emit_move_insn (temp, gen_rtx_SUBREG (<VDC:VDBL>mode, operands[1], offset));
3579 emit_move_insn (operands[0], gen_lowpart (<VDC:MODE>mode, temp));
3585 (define_expand "aarch64_get_qreg<VSTRUCT:mode><VQ:mode>"
3586 [(match_operand:VQ 0 "register_operand" "=w")
3587 (match_operand:VSTRUCT 1 "register_operand" "w")
3588 (match_operand:SI 2 "immediate_operand" "i")]
3591 int part = INTVAL (operands[2]);
3592 int offset = part * 16;
3594 emit_move_insn (operands[0],
3595 gen_rtx_SUBREG (<VQ:MODE>mode, operands[1], offset));
3599 ;; Permuted-store expanders for neon intrinsics.
3601 ;; Permute instructions
3605 (define_expand "vec_perm_const<mode>"
3606 [(match_operand:VALL 0 "register_operand")
3607 (match_operand:VALL 1 "register_operand")
3608 (match_operand:VALL 2 "register_operand")
3609 (match_operand:<V_cmp_result> 3)]
3612 if (aarch64_expand_vec_perm_const (operands[0], operands[1],
3613 operands[2], operands[3]))
3619 (define_expand "vec_perm<mode>"
3620 [(match_operand:VB 0 "register_operand")
3621 (match_operand:VB 1 "register_operand")
3622 (match_operand:VB 2 "register_operand")
3623 (match_operand:VB 3 "register_operand")]
3626 aarch64_expand_vec_perm (operands[0], operands[1],
3627 operands[2], operands[3]);
3631 (define_insn "aarch64_tbl1<mode>"
3632 [(set (match_operand:VB 0 "register_operand" "=w")
3633 (unspec:VB [(match_operand:V16QI 1 "register_operand" "w")
3634 (match_operand:VB 2 "register_operand" "w")]
3637 "tbl\\t%0.<Vtype>, {%1.16b}, %2.<Vtype>"
3638 [(set_attr "simd_type" "simd_tbl")
3639 (set_attr "simd_mode" "<MODE>")]
3642 ;; Two source registers.
3644 (define_insn "aarch64_tbl2v16qi"
3645 [(set (match_operand:V16QI 0 "register_operand" "=w")
3646 (unspec:V16QI [(match_operand:OI 1 "register_operand" "w")
3647 (match_operand:V16QI 2 "register_operand" "w")]
3650 "tbl\\t%0.16b, {%S1.16b - %T1.16b}, %2.16b"
3651 [(set_attr "simd_type" "simd_tbl")
3652 (set_attr "simd_mode" "V16QI")]
3655 (define_insn_and_split "aarch64_combinev16qi"
3656 [(set (match_operand:OI 0 "register_operand" "=w")
3657 (unspec:OI [(match_operand:V16QI 1 "register_operand" "w")
3658 (match_operand:V16QI 2 "register_operand" "w")]
3662 "&& reload_completed"
3665 aarch64_split_combinev16qi (operands);
3669 (define_insn "aarch64_<PERMUTE:perm_insn><PERMUTE:perm_hilo><mode>"
3670 [(set (match_operand:VALL 0 "register_operand" "=w")
3671 (unspec:VALL [(match_operand:VALL 1 "register_operand" "w")
3672 (match_operand:VALL 2 "register_operand" "w")]
3675 "<PERMUTE:perm_insn><PERMUTE:perm_hilo>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
3676 [(set_attr "simd_type" "simd_<PERMUTE:perm_insn>")
3677 (set_attr "simd_mode" "<MODE>")]
3680 (define_insn "aarch64_st2<mode>_dreg"
3681 [(set (match_operand:TI 0 "aarch64_simd_struct_operand" "=Utv")
3682 (unspec:TI [(match_operand:OI 1 "register_operand" "w")
3683 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3686 "st2\\t{%S1.<Vtype> - %T1.<Vtype>}, %0"
3687 [(set_attr "simd_type" "simd_store2")
3688 (set_attr "simd_mode" "<MODE>")])
3690 (define_insn "aarch64_st2<mode>_dreg"
3691 [(set (match_operand:TI 0 "aarch64_simd_struct_operand" "=Utv")
3692 (unspec:TI [(match_operand:OI 1 "register_operand" "w")
3693 (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3696 "st1\\t{%S1.1d - %T1.1d}, %0"
3697 [(set_attr "simd_type" "simd_store2")
3698 (set_attr "simd_mode" "<MODE>")])
3700 (define_insn "aarch64_st3<mode>_dreg"
3701 [(set (match_operand:EI 0 "aarch64_simd_struct_operand" "=Utv")
3702 (unspec:EI [(match_operand:CI 1 "register_operand" "w")
3703 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3706 "st3\\t{%S1.<Vtype> - %U1.<Vtype>}, %0"
3707 [(set_attr "simd_type" "simd_store3")
3708 (set_attr "simd_mode" "<MODE>")])
3710 (define_insn "aarch64_st3<mode>_dreg"
3711 [(set (match_operand:EI 0 "aarch64_simd_struct_operand" "=Utv")
3712 (unspec:EI [(match_operand:CI 1 "register_operand" "w")
3713 (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3716 "st1\\t{%S1.1d - %U1.1d}, %0"
3717 [(set_attr "simd_type" "simd_store3")
3718 (set_attr "simd_mode" "<MODE>")])
3720 (define_insn "aarch64_st4<mode>_dreg"
3721 [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
3722 (unspec:OI [(match_operand:XI 1 "register_operand" "w")
3723 (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3726 "st4\\t{%S1.<Vtype> - %V1.<Vtype>}, %0"
3727 [(set_attr "simd_type" "simd_store4")
3728 (set_attr "simd_mode" "<MODE>")])
3730 (define_insn "aarch64_st4<mode>_dreg"
3731 [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
3732 (unspec:OI [(match_operand:XI 1 "register_operand" "w")
3733 (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3736 "st1\\t{%S1.1d - %V1.1d}, %0"
3737 [(set_attr "simd_type" "simd_store4")
3738 (set_attr "simd_mode" "<MODE>")])
3740 (define_expand "aarch64_st<VSTRUCT:nregs><VDC:mode>"
3741 [(match_operand:DI 0 "register_operand" "r")
3742 (match_operand:VSTRUCT 1 "register_operand" "w")
3743 (unspec:VDC [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3746 enum machine_mode mode = <VSTRUCT:VSTRUCT_DREG>mode;
3747 rtx mem = gen_rtx_MEM (mode, operands[0]);
3749 emit_insn (gen_aarch64_st<VSTRUCT:nregs><VDC:mode>_dreg (mem, operands[1]));
3753 (define_expand "aarch64_st<VSTRUCT:nregs><VQ:mode>"
3754 [(match_operand:DI 0 "register_operand" "r")
3755 (match_operand:VSTRUCT 1 "register_operand" "w")
3756 (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3759 enum machine_mode mode = <VSTRUCT:MODE>mode;
3760 rtx mem = gen_rtx_MEM (mode, operands[0]);
3762 emit_insn (gen_vec_store_lanes<VSTRUCT:mode><VQ:mode> (mem, operands[1]));
3766 ;; Expander for builtins to insert vector registers into large
3767 ;; opaque integer modes.
3769 ;; Q-register list. We don't need a D-reg inserter as we zero
3770 ;; extend them in arm_neon.h and insert the resulting Q-regs.
3772 (define_expand "aarch64_set_qreg<VSTRUCT:mode><VQ:mode>"
3773 [(match_operand:VSTRUCT 0 "register_operand" "+w")
3774 (match_operand:VSTRUCT 1 "register_operand" "0")
3775 (match_operand:VQ 2 "register_operand" "w")
3776 (match_operand:SI 3 "immediate_operand" "i")]
3779 int part = INTVAL (operands[3]);
3780 int offset = part * 16;
3782 emit_move_insn (operands[0], operands[1]);
3783 emit_move_insn (gen_rtx_SUBREG (<VQ:MODE>mode, operands[0], offset),
3788 ;; Standard pattern name vec_init<mode>.
3790 (define_expand "vec_init<mode>"
3791 [(match_operand:VALL 0 "register_operand" "")
3792 (match_operand 1 "" "")]
3795 aarch64_expand_vector_init (operands[0], operands[1]);
3799 (define_insn "*aarch64_simd_ld1r<mode>"
3800 [(set (match_operand:VALLDI 0 "register_operand" "=w")
3801 (vec_duplicate:VALLDI
3802 (match_operand:<VEL> 1 "aarch64_simd_struct_operand" "Utv")))]
3804 "ld1r\\t{%0.<Vtype>}, %1"
3805 [(set_attr "simd_type" "simd_load1r")
3806 (set_attr "simd_mode" "<MODE>")])
3808 (define_insn "aarch64_frecpe<mode>"
3809 [(set (match_operand:VDQF 0 "register_operand" "=w")
3810 (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")]
3813 "frecpe\\t%0.<Vtype>, %1.<Vtype>"
3814 [(set_attr "simd_type" "simd_frecpe")
3815 (set_attr "simd_mode" "<MODE>")]
3818 (define_insn "aarch64_frecps<mode>"
3819 [(set (match_operand:VDQF 0 "register_operand" "=w")
3820 (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")
3821 (match_operand:VDQF 2 "register_operand" "w")]
3824 "frecps\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
3825 [(set_attr "simd_type" "simd_frecps")
3826 (set_attr "simd_mode" "<MODE>")]