aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8.1/gcc/config/aarch64/aarch64-simd.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8.1/gcc/config/aarch64/aarch64-simd.md')
-rw-r--r--gcc-4.8.1/gcc/config/aarch64/aarch64-simd.md3716
1 files changed, 0 insertions, 3716 deletions
diff --git a/gcc-4.8.1/gcc/config/aarch64/aarch64-simd.md b/gcc-4.8.1/gcc/config/aarch64/aarch64-simd.md
deleted file mode 100644
index 79c309331..000000000
--- a/gcc-4.8.1/gcc/config/aarch64/aarch64-simd.md
+++ /dev/null
@@ -1,3716 +0,0 @@
-;; Machine description for AArch64 AdvSIMD architecture.
-;; Copyright (C) 2011-2013 Free Software Foundation, Inc.
-;; Contributed by ARM Ltd.
-;;
-;; This file is part of GCC.
-;;
-;; GCC is free software; you can redistribute it and/or modify it
-;; under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
-;;
-;; GCC is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-;; General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GCC; see the file COPYING3. If not see
-;; <http://www.gnu.org/licenses/>.
-
-
-; Main data types used by the insntructions
-
-(define_attr "simd_mode" "unknown,none,V8QI,V16QI,V4HI,V8HI,V2SI,V4SI,V2DI,V2SF,V4SF,V2DF,OI,CI,XI,DI,DF,SI,HI,QI"
- (const_string "unknown"))
-
-
-; Classification of AdvSIMD instructions for scheduling purposes.
-; Do not set this attribute and the "v8type" attribute together in
-; any instruction pattern.
-
-; simd_abd integer absolute difference and accumulate.
-; simd_abdl integer absolute difference and accumulate (long).
-; simd_adal integer add and accumulate (long).
-; simd_add integer addition/subtraction.
-; simd_addl integer addition/subtraction (long).
-; simd_addlv across lanes integer sum (long).
-; simd_addn integer addition/subtraction (narrow).
-; simd_addn2 integer addition/subtraction (narrow, high).
-; simd_addv across lanes integer sum.
-; simd_cls count leading sign/zero bits.
-; simd_cmp compare / create mask.
-; simd_cnt population count.
-; simd_dup duplicate element.
-; simd_dupgp duplicate general purpose register.
-; simd_ext bitwise extract from pair.
-; simd_fadd floating point add/sub.
-; simd_fcmp floating point compare.
-; simd_fcvti floating point convert to integer.
-; simd_fcvtl floating-point convert upsize.
-; simd_fcvtn floating-point convert downsize (narrow).
-; simd_fcvtn2 floating-point convert downsize (narrow, high).
-; simd_fdiv floating point division.
-; simd_fminmax floating point min/max.
-; simd_fminmaxv across lanes floating point min/max.
-; simd_fmla floating point multiply-add.
-; simd_fmla_elt floating point multiply-add (by element).
-; simd_fmul floating point multiply.
-; simd_fmul_elt floating point multiply (by element).
-; simd_fnegabs floating point neg/abs.
-; simd_frcpe floating point reciprocal estimate.
-; simd_frcps floating point reciprocal step.
-; simd_frecx floating point reciprocal exponent.
-; simd_frint floating point round to integer.
-; simd_fsqrt floating point square root.
-; simd_icvtf integer convert to floating point.
-; simd_ins insert element.
-; simd_insgp insert general purpose register.
-; simd_load1 load multiple structures to one register (LD1).
-; simd_load1r load single structure to all lanes of one register (LD1R).
-; simd_load1s load single structure to one lane of one register (LD1 [index]).
-; simd_load2 load multiple structures to two registers (LD1, LD2).
-; simd_load2r load single structure to all lanes of two registers (LD1R, LD2R).
-; simd_load2s load single structure to one lane of two registers (LD2 [index]).
-; simd_load3 load multiple structures to three registers (LD1, LD3).
-; simd_load3r load single structure to all lanes of three registers (LD3R).
-; simd_load3s load single structure to one lane of three registers (LD3 [index]).
-; simd_load4 load multiple structures to four registers (LD1, LD2, LD4).
-; simd_load4r load single structure to all lanes of four registers (LD4R).
-; simd_load4s load single structure to one lane of four registers (LD4 [index]).
-; simd_logic logical operation.
-; simd_logic_imm logcial operation (immediate).
-; simd_minmax integer min/max.
-; simd_minmaxv across lanes integer min/max,
-; simd_mla integer multiply-accumulate.
-; simd_mla_elt integer multiply-accumulate (by element).
-; simd_mlal integer multiply-accumulate (long).
-; simd_mlal_elt integer multiply-accumulate (by element, long).
-; simd_move move register.
-; simd_move_imm move immediate.
-; simd_movgp move element to general purpose register.
-; simd_mul integer multiply.
-; simd_mul_elt integer multiply (by element).
-; simd_mull integer multiply (long).
-; simd_mull_elt integer multiply (by element, long).
-; simd_negabs integer negate/absolute.
-; simd_rbit bitwise reverse.
-; simd_rcpe integer reciprocal estimate.
-; simd_rcps integer reciprocal square root.
-; simd_rev element reverse.
-; simd_sat_add integer saturating addition/subtraction.
-; simd_sat_mlal integer saturating multiply-accumulate (long).
-; simd_sat_mlal_elt integer saturating multiply-accumulate (by element, long).
-; simd_sat_mul integer saturating multiply.
-; simd_sat_mul_elt integer saturating multiply (by element).
-; simd_sat_mull integer saturating multiply (long).
-; simd_sat_mull_elt integer saturating multiply (by element, long).
-; simd_sat_negabs integer saturating negate/absolute.
-; simd_sat_shift integer saturating shift.
-; simd_sat_shift_imm integer saturating shift (immediate).
-; simd_sat_shiftn_imm integer saturating shift (narrow, immediate).
-; simd_sat_shiftn2_imm integer saturating shift (narrow, high, immediate).
-; simd_shift shift register/vector.
-; simd_shift_acc shift accumulate.
-; simd_shift_imm shift immediate.
-; simd_shift_imm_acc shift immediate and accumualte.
-; simd_shiftl shift register/vector (long).
-; simd_shiftl_imm shift register/vector (long, immediate).
-; simd_shiftn_imm shift register/vector (narrow, immediate).
-; simd_shiftn2_imm shift register/vector (narrow, high, immediate).
-; simd_store1 store multiple structures from one register (ST1).
-; simd_store1s store single structure from one lane of one register (ST1 [index]).
-; simd_store2 store multiple structures from two registers (ST1, ST2).
-; simd_store2s store single structure from one lane of two registers (ST2 [index]).
-; simd_store3 store multiple structures from three registers (ST1, ST3).
-; simd_store3s store single structure from one lane of three register (ST3 [index]).
-; simd_store4 store multiple structures from four registers (ST1, ST2, ST4).
-; simd_store4s store single structure from one lane for four registers (ST4 [index]).
-; simd_tbl table lookup.
-; simd_trn transpose.
-; simd_uzp unzip.
-; simd_zip zip.
-
-(define_attr "simd_type"
- "simd_abd,\
- simd_abdl,\
- simd_adal,\
- simd_add,\
- simd_addl,\
- simd_addlv,\
- simd_addn,\
- simd_addn2,\
- simd_addv,\
- simd_cls,\
- simd_cmp,\
- simd_cnt,\
- simd_dup,\
- simd_dupgp,\
- simd_ext,\
- simd_fadd,\
- simd_fcmp,\
- simd_fcvti,\
- simd_fcvtl,\
- simd_fcvtn,\
- simd_fcvtn2,\
- simd_fdiv,\
- simd_fminmax,\
- simd_fminmaxv,\
- simd_fmla,\
- simd_fmla_elt,\
- simd_fmul,\
- simd_fmul_elt,\
- simd_fnegabs,\
- simd_frcpe,\
- simd_frcps,\
- simd_frecx,\
- simd_frint,\
- simd_fsqrt,\
- simd_icvtf,\
- simd_ins,\
- simd_insgp,\
- simd_load1,\
- simd_load1r,\
- simd_load1s,\
- simd_load2,\
- simd_load2r,\
- simd_load2s,\
- simd_load3,\
- simd_load3r,\
- simd_load3s,\
- simd_load4,\
- simd_load4r,\
- simd_load4s,\
- simd_logic,\
- simd_logic_imm,\
- simd_minmax,\
- simd_minmaxv,\
- simd_mla,\
- simd_mla_elt,\
- simd_mlal,\
- simd_mlal_elt,\
- simd_movgp,\
- simd_move,\
- simd_move_imm,\
- simd_mul,\
- simd_mul_elt,\
- simd_mull,\
- simd_mull_elt,\
- simd_negabs,\
- simd_rbit,\
- simd_rcpe,\
- simd_rcps,\
- simd_rev,\
- simd_sat_add,\
- simd_sat_mlal,\
- simd_sat_mlal_elt,\
- simd_sat_mul,\
- simd_sat_mul_elt,\
- simd_sat_mull,\
- simd_sat_mull_elt,\
- simd_sat_negabs,\
- simd_sat_shift,\
- simd_sat_shift_imm,\
- simd_sat_shiftn_imm,\
- simd_sat_shiftn2_imm,\
- simd_shift,\
- simd_shift_acc,\
- simd_shift_imm,\
- simd_shift_imm_acc,\
- simd_shiftl,\
- simd_shiftl_imm,\
- simd_shiftn_imm,\
- simd_shiftn2_imm,\
- simd_store1,\
- simd_store1s,\
- simd_store2,\
- simd_store2s,\
- simd_store3,\
- simd_store3s,\
- simd_store4,\
- simd_store4s,\
- simd_tbl,\
- simd_trn,\
- simd_uzp,\
- simd_zip,\
- none"
- (const_string "none"))
-
-
-; The "neon_type" attribute is used by the AArch32 backend. Below is a mapping
-; from "simd_type" to "neon_type".
-
-(define_attr "neon_type"
- "neon_int_1,neon_int_2,neon_int_3,neon_int_4,neon_int_5,neon_vqneg_vqabs,
- neon_vmov,neon_vaba,neon_vsma,neon_vaba_qqq,
- neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,neon_mul_qqq_8_16_32_ddd_32,
- neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,
- neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,neon_mla_qqq_8_16,
- neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,
- neon_mla_qqq_32_qqd_32_scalar,neon_mul_ddd_16_scalar_32_16_long_scalar,
- neon_mul_qqd_32_scalar,neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,
- neon_shift_1,neon_shift_2,neon_shift_3,neon_vshl_ddd,
- neon_vqshl_vrshl_vqrshl_qqq,neon_vsra_vrsra,neon_fp_vadd_ddd_vabs_dd,
- neon_fp_vadd_qqq_vabs_qq,neon_fp_vsum,neon_fp_vmul_ddd,neon_fp_vmul_qqd,
- neon_fp_vmla_ddd,neon_fp_vmla_qqq,neon_fp_vmla_ddd_scalar,
- neon_fp_vmla_qqq_scalar,neon_fp_vrecps_vrsqrts_ddd,
- neon_fp_vrecps_vrsqrts_qqq,neon_bp_simple,neon_bp_2cycle,neon_bp_3cycle,
- neon_ldr,neon_str,neon_vld1_1_2_regs,neon_vld1_3_4_regs,
- neon_vld2_2_regs_vld1_vld2_all_lanes,neon_vld2_4_regs,neon_vld3_vld4,
- neon_vst1_1_2_regs_vst2_2_regs,neon_vst1_3_4_regs,
- neon_vst2_4_regs_vst3_vst4,neon_vst3_vst4,neon_vld1_vld2_lane,
- neon_vld3_vld4_lane,neon_vst1_vst2_lane,neon_vst3_vst4_lane,
- neon_vld3_vld4_all_lanes,neon_mcr,neon_mcr_2_mcrr,neon_mrc,neon_mrrc,
- neon_ldm_2,neon_stm_2,none,unknown"
- (cond [
- (eq_attr "simd_type" "simd_dup") (const_string "neon_bp_simple")
- (eq_attr "simd_type" "simd_movgp") (const_string "neon_bp_simple")
- (eq_attr "simd_type" "simd_add,simd_logic,simd_logic_imm") (const_string "neon_int_1")
- (eq_attr "simd_type" "simd_negabs,simd_addlv") (const_string "neon_int_3")
- (eq_attr "simd_type" "simd_addn,simd_addn2,simd_addl,simd_sat_add,simd_sat_negabs") (const_string "neon_int_4")
- (eq_attr "simd_type" "simd_move") (const_string "neon_vmov")
- (eq_attr "simd_type" "simd_ins") (const_string "neon_mcr")
- (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")
- (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")
- (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")
- (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")
- (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")
- (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")
- (and (eq_attr "simd_type" "simd_mla,simd_sat_mlal") (eq_attr "simd_mode" "V16QI,V8HI")) (const_string "neon_mla_qqq_8_16")
- (and (eq_attr "simd_type" "simd_mla,simd_sat_mlal") (eq_attr "simd_mode" "V4SI")) (const_string "neon_mla_qqq_32_qqd_32_scalar")
- (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")
- (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")
- (and (eq_attr "simd_type" "simd_fmla") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vmla_ddd")
- (and (eq_attr "simd_type" "simd_fmla") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vmla_qqq")
- (and (eq_attr "simd_type" "simd_fmla_elt") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vmla_ddd_scalar")
- (and (eq_attr "simd_type" "simd_fmla_elt") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vmla_qqq_scalar")
- (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")
- (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")
- (and (eq_attr "simd_type" "simd_fadd") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vadd_ddd_vabs_dd")
- (and (eq_attr "simd_type" "simd_fadd") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vadd_qqq_vabs_qq")
- (and (eq_attr "simd_type" "simd_fnegabs,simd_fminmax,simd_fminmaxv") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vadd_ddd_vabs_dd")
- (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")
- (and (eq_attr "simd_type" "simd_shift,simd_shift_acc") (eq_attr "simd_mode" "V8QI,V4HI,V2SI")) (const_string "neon_vshl_ddd")
- (and (eq_attr "simd_type" "simd_shift,simd_shift_acc") (eq_attr "simd_mode" "V16QI,V8HI,V4SI,V2DI")) (const_string "neon_shift_3")
- (eq_attr "simd_type" "simd_minmax,simd_minmaxv") (const_string "neon_int_5")
- (eq_attr "simd_type" "simd_shiftn_imm,simd_shiftn2_imm,simd_shiftl_imm,") (const_string "neon_shift_1")
- (eq_attr "simd_type" "simd_load1,simd_load2") (const_string "neon_vld1_1_2_regs")
- (eq_attr "simd_type" "simd_load3,simd_load3") (const_string "neon_vld1_3_4_regs")
- (eq_attr "simd_type" "simd_load1r,simd_load2r,simd_load3r,simd_load4r") (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
- (eq_attr "simd_type" "simd_load1s,simd_load2s") (const_string "neon_vld1_vld2_lane")
- (eq_attr "simd_type" "simd_load3s,simd_load4s") (const_string "neon_vld3_vld4_lane")
- (eq_attr "simd_type" "simd_store1,simd_store2") (const_string "neon_vst1_1_2_regs_vst2_2_regs")
- (eq_attr "simd_type" "simd_store3,simd_store4") (const_string "neon_vst1_3_4_regs")
- (eq_attr "simd_type" "simd_store1s,simd_store2s") (const_string "neon_vst1_vst2_lane")
- (eq_attr "simd_type" "simd_store3s,simd_store4s") (const_string "neon_vst3_vst4_lane")
- (and (eq_attr "simd_type" "simd_frcpe,simd_frcps") (eq_attr "simd_mode" "V2SF")) (const_string "neon_fp_vrecps_vrsqrts_ddd")
- (and (eq_attr "simd_type" "simd_frcpe,simd_frcps") (eq_attr "simd_mode" "V4SF,V2DF")) (const_string "neon_fp_vrecps_vrsqrts_qqq")
- (eq_attr "simd_type" "none") (const_string "none")
- ]
- (const_string "unknown")))
-
-
-(define_expand "mov<mode>"
- [(set (match_operand:VALL 0 "aarch64_simd_nonimmediate_operand" "")
- (match_operand:VALL 1 "aarch64_simd_general_operand" ""))]
- "TARGET_SIMD"
- "
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (<MODE>mode, operands[1]);
- "
-)
-
-(define_expand "movmisalign<mode>"
- [(set (match_operand:VALL 0 "aarch64_simd_nonimmediate_operand" "")
- (match_operand:VALL 1 "aarch64_simd_general_operand" ""))]
- "TARGET_SIMD"
-{
- /* This pattern is not permitted to fail during expansion: if both arguments
- are non-registers (e.g. memory := constant, which can be created by the
- auto-vectorizer), force operand 1 into a register. */
- if (!register_operand (operands[0], <MODE>mode)
- && !register_operand (operands[1], <MODE>mode))
- operands[1] = force_reg (<MODE>mode, operands[1]);
-})
-
-(define_insn "aarch64_simd_dup<mode>"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (vec_duplicate:VDQ (match_operand:<VEL> 1 "register_operand" "r")))]
- "TARGET_SIMD"
- "dup\\t%0.<Vtype>, %<vw>1"
- [(set_attr "simd_type" "simd_dupgp")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_dup_lane<mode>"
- [(set (match_operand:VDQ_I 0 "register_operand" "=w")
- (vec_duplicate:VDQ_I
- (vec_select:<VEL>
- (match_operand:<VCON> 1 "register_operand" "w")
- (parallel [(match_operand:SI 2 "immediate_operand" "i")])
- )))]
- "TARGET_SIMD"
- "dup\\t%<v>0<Vmtype>, %1.<Vetype>[%2]"
- [(set_attr "simd_type" "simd_dup")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_dup_lane<mode>"
- [(set (match_operand:SDQ_I 0 "register_operand" "=w")
- (vec_select:<VEL>
- (match_operand:<VCON> 1 "register_operand" "w")
- (parallel [(match_operand:SI 2 "immediate_operand" "i")])
- ))]
- "TARGET_SIMD"
- "dup\\t%<v>0<Vmtype>, %1.<Vetype>[%2]"
- [(set_attr "simd_type" "simd_dup")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_simd_dup<mode>"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (vec_duplicate:VDQF (match_operand:<VEL> 1 "register_operand" "w")))]
- "TARGET_SIMD"
- "dup\\t%0.<Vtype>, %1.<Vetype>[0]"
- [(set_attr "simd_type" "simd_dup")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "*aarch64_simd_mov<mode>"
- [(set (match_operand:VD 0 "aarch64_simd_nonimmediate_operand"
- "=w, Utv, w, ?r, ?w, ?r, w")
- (match_operand:VD 1 "aarch64_simd_general_operand"
- "Utv, w, w, w, r, r, Dn"))]
- "TARGET_SIMD
- && (register_operand (operands[0], <MODE>mode)
- || register_operand (operands[1], <MODE>mode))"
-{
- switch (which_alternative)
- {
- case 0: return "ld1\t{%0.<Vtype>}, %1";
- case 1: return "st1\t{%1.<Vtype>}, %0";
- case 2: return "orr\t%0.<Vbtype>, %1.<Vbtype>, %1.<Vbtype>";
- case 3: return "umov\t%0, %1.d[0]";
- case 4: return "ins\t%0.d[0], %1";
- case 5: return "mov\t%0, %1";
- case 6:
- return aarch64_output_simd_mov_immediate (&operands[1],
- <MODE>mode, 64);
- default: gcc_unreachable ();
- }
-}
- [(set_attr "simd_type" "simd_load1,simd_store1,simd_move,simd_movgp,simd_insgp,simd_move,simd_move_imm")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "*aarch64_simd_mov<mode>"
- [(set (match_operand:VQ 0 "aarch64_simd_nonimmediate_operand"
- "=w, Utv, w, ?r, ?w, ?r, w")
- (match_operand:VQ 1 "aarch64_simd_general_operand"
- "Utv, w, w, w, r, r, Dn"))]
- "TARGET_SIMD
- && (register_operand (operands[0], <MODE>mode)
- || register_operand (operands[1], <MODE>mode))"
-{
- switch (which_alternative)
- {
- case 0: return "ld1\t{%0.<Vtype>}, %1";
- case 1: return "st1\t{%1.<Vtype>}, %0";
- case 2: return "orr\t%0.<Vbtype>, %1.<Vbtype>, %1.<Vbtype>";
- case 3: return "umov\t%0, %1.d[0]\;umov\t%H0, %1.d[1]";
- case 4: return "ins\t%0.d[0], %1\;ins\t%0.d[1], %H1";
- case 5: return "#";
- case 6:
- return aarch64_output_simd_mov_immediate (&operands[1],
- <MODE>mode, 128);
- default: gcc_unreachable ();
- }
-}
- [(set_attr "simd_type" "simd_load1,simd_store1,simd_move,simd_movgp,simd_insgp,simd_move,simd_move_imm")
- (set_attr "simd_mode" "<MODE>")
- (set_attr "length" "4,4,4,8,8,8,4")]
-)
-
-(define_split
- [(set (match_operand:VQ 0 "register_operand" "")
- (match_operand:VQ 1 "register_operand" ""))]
- "TARGET_SIMD && reload_completed
- && GP_REGNUM_P (REGNO (operands[0]))
- && GP_REGNUM_P (REGNO (operands[1]))"
- [(set (match_dup 0) (match_dup 1))
- (set (match_dup 2) (match_dup 3))]
-{
- int rdest = REGNO (operands[0]);
- int rsrc = REGNO (operands[1]);
- rtx dest[2], src[2];
-
- dest[0] = gen_rtx_REG (DImode, rdest);
- src[0] = gen_rtx_REG (DImode, rsrc);
- dest[1] = gen_rtx_REG (DImode, rdest + 1);
- src[1] = gen_rtx_REG (DImode, rsrc + 1);
-
- aarch64_simd_disambiguate_copy (operands, dest, src, 2);
-})
-
-(define_insn "orn<mode>3"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (ior:VDQ (not:VDQ (match_operand:VDQ 1 "register_operand" "w"))
- (match_operand:VDQ 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "orn\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
- [(set_attr "simd_type" "simd_logic")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "bic<mode>3"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (and:VDQ (not:VDQ (match_operand:VDQ 1 "register_operand" "w"))
- (match_operand:VDQ 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "bic\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
- [(set_attr "simd_type" "simd_logic")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "add<mode>3"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (plus:VDQ (match_operand:VDQ 1 "register_operand" "w")
- (match_operand:VDQ 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "add\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_add")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "sub<mode>3"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (minus:VDQ (match_operand:VDQ 1 "register_operand" "w")
- (match_operand:VDQ 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "sub\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_add")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "mul<mode>3"
- [(set (match_operand:VDQM 0 "register_operand" "=w")
- (mult:VDQM (match_operand:VDQM 1 "register_operand" "w")
- (match_operand:VDQM 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "mul\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_mul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "neg<mode>2"
- [(set (match_operand:VDQM 0 "register_operand" "=w")
- (neg:VDQM (match_operand:VDQM 1 "register_operand" "w")))]
- "TARGET_SIMD"
- "neg\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_negabs")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "abs<mode>2"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (abs:VDQ (match_operand:VDQ 1 "register_operand" "w")))]
- "TARGET_SIMD"
- "abs\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_negabs")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "and<mode>3"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (and:VDQ (match_operand:VDQ 1 "register_operand" "w")
- (match_operand:VDQ 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "and\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
- [(set_attr "simd_type" "simd_logic")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "ior<mode>3"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (ior:VDQ (match_operand:VDQ 1 "register_operand" "w")
- (match_operand:VDQ 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "orr\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
- [(set_attr "simd_type" "simd_logic")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "xor<mode>3"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (xor:VDQ (match_operand:VDQ 1 "register_operand" "w")
- (match_operand:VDQ 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "eor\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
- [(set_attr "simd_type" "simd_logic")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "one_cmpl<mode>2"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (not:VDQ (match_operand:VDQ 1 "register_operand" "w")))]
- "TARGET_SIMD"
- "not\t%0.<Vbtype>, %1.<Vbtype>"
- [(set_attr "simd_type" "simd_logic")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_simd_vec_set<mode>"
- [(set (match_operand:VQ_S 0 "register_operand" "=w")
- (vec_merge:VQ_S
- (vec_duplicate:VQ_S
- (match_operand:<VEL> 1 "register_operand" "r"))
- (match_operand:VQ_S 3 "register_operand" "0")
- (match_operand:SI 2 "immediate_operand" "i")))]
- "TARGET_SIMD"
- "ins\t%0.<Vetype>[%p2], %w1";
- [(set_attr "simd_type" "simd_insgp")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_simd_lshr<mode>"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (lshiftrt:VDQ (match_operand:VDQ 1 "register_operand" "w")
- (match_operand:VDQ 2 "aarch64_simd_rshift_imm" "Dr")))]
- "TARGET_SIMD"
- "ushr\t%0.<Vtype>, %1.<Vtype>, %2"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_simd_ashr<mode>"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (ashiftrt:VDQ (match_operand:VDQ 1 "register_operand" "w")
- (match_operand:VDQ 2 "aarch64_simd_rshift_imm" "Dr")))]
- "TARGET_SIMD"
- "sshr\t%0.<Vtype>, %1.<Vtype>, %2"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_simd_imm_shl<mode>"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (ashift:VDQ (match_operand:VDQ 1 "register_operand" "w")
- (match_operand:VDQ 2 "aarch64_simd_lshift_imm" "Dl")))]
- "TARGET_SIMD"
- "shl\t%0.<Vtype>, %1.<Vtype>, %2"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_simd_reg_sshl<mode>"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (ashift:VDQ (match_operand:VDQ 1 "register_operand" "w")
- (match_operand:VDQ 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "sshl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_shift")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_simd_reg_shl<mode>_unsigned"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (unspec:VDQ [(match_operand:VDQ 1 "register_operand" "w")
- (match_operand:VDQ 2 "register_operand" "w")]
- UNSPEC_ASHIFT_UNSIGNED))]
- "TARGET_SIMD"
- "ushl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_shift")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_simd_reg_shl<mode>_signed"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (unspec:VDQ [(match_operand:VDQ 1 "register_operand" "w")
- (match_operand:VDQ 2 "register_operand" "w")]
- UNSPEC_ASHIFT_SIGNED))]
- "TARGET_SIMD"
- "sshl\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_shift")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "ashl<mode>3"
- [(match_operand:VDQ 0 "register_operand" "")
- (match_operand:VDQ 1 "register_operand" "")
- (match_operand:SI 2 "general_operand" "")]
- "TARGET_SIMD"
-{
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- int shift_amount;
-
- if (CONST_INT_P (operands[2]))
- {
- shift_amount = INTVAL (operands[2]);
- if (shift_amount >= 0 && shift_amount < bit_width)
- {
- rtx tmp = aarch64_simd_gen_const_vector_dup (<MODE>mode,
- shift_amount);
- emit_insn (gen_aarch64_simd_imm_shl<mode> (operands[0],
- operands[1],
- tmp));
- DONE;
- }
- else
- {
- operands[2] = force_reg (SImode, operands[2]);
- }
- }
- else if (MEM_P (operands[2]))
- {
- operands[2] = force_reg (SImode, operands[2]);
- }
-
- if (REG_P (operands[2]))
- {
- rtx tmp = gen_reg_rtx (<MODE>mode);
- emit_insn (gen_aarch64_simd_dup<mode> (tmp,
- convert_to_mode (<VEL>mode,
- operands[2],
- 0)));
- emit_insn (gen_aarch64_simd_reg_sshl<mode> (operands[0], operands[1],
- tmp));
- DONE;
- }
- else
- FAIL;
-}
-)
-
-(define_expand "lshr<mode>3"
- [(match_operand:VDQ 0 "register_operand" "")
- (match_operand:VDQ 1 "register_operand" "")
- (match_operand:SI 2 "general_operand" "")]
- "TARGET_SIMD"
-{
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- int shift_amount;
-
- if (CONST_INT_P (operands[2]))
- {
- shift_amount = INTVAL (operands[2]);
- if (shift_amount > 0 && shift_amount <= bit_width)
- {
- rtx tmp = aarch64_simd_gen_const_vector_dup (<MODE>mode,
- shift_amount);
- emit_insn (gen_aarch64_simd_lshr<mode> (operands[0],
- operands[1],
- tmp));
- DONE;
- }
- else
- operands[2] = force_reg (SImode, operands[2]);
- }
- else if (MEM_P (operands[2]))
- {
- operands[2] = force_reg (SImode, operands[2]);
- }
-
- if (REG_P (operands[2]))
- {
- rtx tmp = gen_reg_rtx (SImode);
- rtx tmp1 = gen_reg_rtx (<MODE>mode);
- emit_insn (gen_negsi2 (tmp, operands[2]));
- emit_insn (gen_aarch64_simd_dup<mode> (tmp1,
- convert_to_mode (<VEL>mode,
- tmp, 0)));
- emit_insn (gen_aarch64_simd_reg_shl<mode>_unsigned (operands[0],
- operands[1],
- tmp1));
- DONE;
- }
- else
- FAIL;
-}
-)
-
-(define_expand "ashr<mode>3"
- [(match_operand:VDQ 0 "register_operand" "")
- (match_operand:VDQ 1 "register_operand" "")
- (match_operand:SI 2 "general_operand" "")]
- "TARGET_SIMD"
-{
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- int shift_amount;
-
- if (CONST_INT_P (operands[2]))
- {
- shift_amount = INTVAL (operands[2]);
- if (shift_amount > 0 && shift_amount <= bit_width)
- {
- rtx tmp = aarch64_simd_gen_const_vector_dup (<MODE>mode,
- shift_amount);
- emit_insn (gen_aarch64_simd_ashr<mode> (operands[0],
- operands[1],
- tmp));
- DONE;
- }
- else
- operands[2] = force_reg (SImode, operands[2]);
- }
- else if (MEM_P (operands[2]))
- {
- operands[2] = force_reg (SImode, operands[2]);
- }
-
- if (REG_P (operands[2]))
- {
- rtx tmp = gen_reg_rtx (SImode);
- rtx tmp1 = gen_reg_rtx (<MODE>mode);
- emit_insn (gen_negsi2 (tmp, operands[2]));
- emit_insn (gen_aarch64_simd_dup<mode> (tmp1,
- convert_to_mode (<VEL>mode,
- tmp, 0)));
- emit_insn (gen_aarch64_simd_reg_shl<mode>_signed (operands[0],
- operands[1],
- tmp1));
- DONE;
- }
- else
- FAIL;
-}
-)
-
-(define_expand "vashl<mode>3"
- [(match_operand:VDQ 0 "register_operand" "")
- (match_operand:VDQ 1 "register_operand" "")
- (match_operand:VDQ 2 "register_operand" "")]
- "TARGET_SIMD"
-{
- emit_insn (gen_aarch64_simd_reg_sshl<mode> (operands[0], operands[1],
- operands[2]));
- DONE;
-})
-
-;; Using mode VQ_S as there is no V2DImode neg!
-;; Negating individual lanes most certainly offsets the
-;; gain from vectorization.
-(define_expand "vashr<mode>3"
- [(match_operand:VQ_S 0 "register_operand" "")
- (match_operand:VQ_S 1 "register_operand" "")
- (match_operand:VQ_S 2 "register_operand" "")]
- "TARGET_SIMD"
-{
- rtx neg = gen_reg_rtx (<MODE>mode);
- emit (gen_neg<mode>2 (neg, operands[2]));
- emit_insn (gen_aarch64_simd_reg_shl<mode>_signed (operands[0], operands[1],
- neg));
- DONE;
-})
-
-(define_expand "vlshr<mode>3"
- [(match_operand:VQ_S 0 "register_operand" "")
- (match_operand:VQ_S 1 "register_operand" "")
- (match_operand:VQ_S 2 "register_operand" "")]
- "TARGET_SIMD"
-{
- rtx neg = gen_reg_rtx (<MODE>mode);
- emit (gen_neg<mode>2 (neg, operands[2]));
- emit_insn (gen_aarch64_simd_reg_shl<mode>_unsigned (operands[0], operands[1],
- neg));
- DONE;
-})
-
-(define_expand "vec_set<mode>"
- [(match_operand:VQ_S 0 "register_operand" "+w")
- (match_operand:<VEL> 1 "register_operand" "r")
- (match_operand:SI 2 "immediate_operand" "")]
- "TARGET_SIMD"
- {
- HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
- emit_insn (gen_aarch64_simd_vec_set<mode> (operands[0], operands[1],
- GEN_INT (elem), operands[0]));
- DONE;
- }
-)
-
-(define_insn "aarch64_simd_vec_setv2di"
- [(set (match_operand:V2DI 0 "register_operand" "=w")
- (vec_merge:V2DI
- (vec_duplicate:V2DI
- (match_operand:DI 1 "register_operand" "r"))
- (match_operand:V2DI 3 "register_operand" "0")
- (match_operand:SI 2 "immediate_operand" "i")))]
- "TARGET_SIMD"
- "ins\t%0.d[%p2], %1";
- [(set_attr "simd_type" "simd_insgp")
- (set_attr "simd_mode" "V2DI")]
-)
-
-(define_expand "vec_setv2di"
- [(match_operand:V2DI 0 "register_operand" "+w")
- (match_operand:DI 1 "register_operand" "r")
- (match_operand:SI 2 "immediate_operand" "")]
- "TARGET_SIMD"
- {
- HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
- emit_insn (gen_aarch64_simd_vec_setv2di (operands[0], operands[1],
- GEN_INT (elem), operands[0]));
- DONE;
- }
-)
-
-(define_insn "aarch64_simd_vec_set<mode>"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (vec_merge:VDQF
- (vec_duplicate:VDQF
- (match_operand:<VEL> 1 "register_operand" "w"))
- (match_operand:VDQF 3 "register_operand" "0")
- (match_operand:SI 2 "immediate_operand" "i")))]
- "TARGET_SIMD"
- "ins\t%0.<Vetype>[%p2], %1.<Vetype>[0]";
- [(set_attr "simd_type" "simd_ins")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "vec_set<mode>"
- [(match_operand:VDQF 0 "register_operand" "+w")
- (match_operand:<VEL> 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "")]
- "TARGET_SIMD"
- {
- HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
- emit_insn (gen_aarch64_simd_vec_set<mode> (operands[0], operands[1],
- GEN_INT (elem), operands[0]));
- DONE;
- }
-)
-
-
-(define_insn "aarch64_mla<mode>"
- [(set (match_operand:VQ_S 0 "register_operand" "=w")
- (plus:VQ_S (mult:VQ_S (match_operand:VQ_S 2 "register_operand" "w")
- (match_operand:VQ_S 3 "register_operand" "w"))
- (match_operand:VQ_S 1 "register_operand" "0")))]
- "TARGET_SIMD"
- "mla\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
- [(set_attr "simd_type" "simd_mla")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_mls<mode>"
- [(set (match_operand:VQ_S 0 "register_operand" "=w")
- (minus:VQ_S (match_operand:VQ_S 1 "register_operand" "0")
- (mult:VQ_S (match_operand:VQ_S 2 "register_operand" "w")
- (match_operand:VQ_S 3 "register_operand" "w"))))]
- "TARGET_SIMD"
- "mls\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
- [(set_attr "simd_type" "simd_mla")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; Max/Min operations.
-(define_insn "<maxmin><mode>3"
- [(set (match_operand:VQ_S 0 "register_operand" "=w")
- (MAXMIN:VQ_S (match_operand:VQ_S 1 "register_operand" "w")
- (match_operand:VQ_S 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "<maxmin>\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_minmax")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; Move into low-half clearing high half to 0.
-
-(define_insn "move_lo_quad_<mode>"
- [(set (match_operand:VQ 0 "register_operand" "=w")
- (vec_concat:VQ
- (match_operand:<VHALF> 1 "register_operand" "w")
- (vec_duplicate:<VHALF> (const_int 0))))]
- "TARGET_SIMD"
- "mov\\t%d0, %d1";
- [(set_attr "simd_type" "simd_dup")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; Move into high-half.
-
-(define_insn "aarch64_simd_move_hi_quad_<mode>"
- [(set (match_operand:VQ 0 "register_operand" "+w")
- (vec_concat:VQ
- (vec_select:<VHALF>
- (match_dup 0)
- (match_operand:VQ 2 "vect_par_cnst_lo_half" ""))
- (match_operand:<VHALF> 1 "register_operand" "w")))]
- "TARGET_SIMD"
- "ins\\t%0.d[1], %1.d[0]";
- [(set_attr "simd_type" "simd_ins")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "move_hi_quad_<mode>"
- [(match_operand:VQ 0 "register_operand" "")
- (match_operand:<VHALF> 1 "register_operand" "")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
- emit_insn (gen_aarch64_simd_move_hi_quad_<mode> (operands[0],
- operands[1], p));
- DONE;
-})
-
-;; Narrowing operations.
-
-;; For doubles.
-(define_insn "aarch64_simd_vec_pack_trunc_<mode>"
- [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
- (truncate:<VNARROWQ> (match_operand:VQN 1 "register_operand" "w")))]
- "TARGET_SIMD"
- "xtn\\t%0.<Vntype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_shiftn_imm")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "vec_pack_trunc_<mode>"
- [(match_operand:<VNARROWD> 0 "register_operand" "")
- (match_operand:VDN 1 "register_operand" "")
- (match_operand:VDN 2 "register_operand" "")]
- "TARGET_SIMD"
-{
- rtx tempreg = gen_reg_rtx (<VDBL>mode);
-
- emit_insn (gen_move_lo_quad_<Vdbl> (tempreg, operands[1]));
- emit_insn (gen_move_hi_quad_<Vdbl> (tempreg, operands[2]));
- emit_insn (gen_aarch64_simd_vec_pack_trunc_<Vdbl> (operands[0], tempreg));
- DONE;
-})
-
-;; For quads.
-
-(define_insn "vec_pack_trunc_<mode>"
- [(set (match_operand:<VNARROWQ2> 0 "register_operand" "+&w")
- (vec_concat:<VNARROWQ2>
- (truncate:<VNARROWQ> (match_operand:VQN 1 "register_operand" "w"))
- (truncate:<VNARROWQ> (match_operand:VQN 2 "register_operand" "w"))))]
- "TARGET_SIMD"
- "xtn\\t%0.<Vntype>, %1.<Vtype>\;xtn2\\t%0.<V2ntype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_shiftn2_imm")
- (set_attr "simd_mode" "<MODE>")
- (set_attr "length" "8")]
-)
-
-;; Widening operations.
-
-(define_insn "aarch64_simd_vec_unpack<su>_lo_<mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
- (match_operand:VQW 1 "register_operand" "w")
- (match_operand:VQW 2 "vect_par_cnst_lo_half" "")
- )))]
- "TARGET_SIMD"
- "<su>shll %0.<Vwtype>, %1.<Vhalftype>, 0"
- [(set_attr "simd_type" "simd_shiftl_imm")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_simd_vec_unpack<su>_hi_<mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
- (match_operand:VQW 1 "register_operand" "w")
- (match_operand:VQW 2 "vect_par_cnst_hi_half" "")
- )))]
- "TARGET_SIMD"
- "<su>shll2 %0.<Vwtype>, %1.<Vtype>, 0"
- [(set_attr "simd_type" "simd_shiftl_imm")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "vec_unpack<su>_hi_<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "")
- (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))]
- "TARGET_SIMD"
- {
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_simd_vec_unpack<su>_hi_<mode> (operands[0],
- operands[1], p));
- DONE;
- }
-)
-
-(define_expand "vec_unpack<su>_lo_<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "")
- (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))]
- "TARGET_SIMD"
- {
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
- emit_insn (gen_aarch64_simd_vec_unpack<su>_lo_<mode> (operands[0],
- operands[1], p));
- DONE;
- }
-)
-
-;; Widening arithmetic.
-
-(define_insn "aarch64_simd_vec_<su>mult_lo_<mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (mult:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
- (match_operand:VQW 1 "register_operand" "w")
- (match_operand:VQW 3 "vect_par_cnst_lo_half" "")))
- (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
- (match_operand:VQW 2 "register_operand" "w")
- (match_dup 3)))))]
- "TARGET_SIMD"
- "<su>mull\\t%0.<Vwtype>, %1.<Vhalftype>, %2.<Vhalftype>"
- [(set_attr "simd_type" "simd_mull")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "vec_widen_<su>mult_lo_<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "")
- (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))
- (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand" ""))]
- "TARGET_SIMD"
- {
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, false);
- emit_insn (gen_aarch64_simd_vec_<su>mult_lo_<mode> (operands[0],
- operands[1],
- operands[2], p));
- DONE;
- }
-)
-
-(define_insn "aarch64_simd_vec_<su>mult_hi_<mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (mult:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
- (match_operand:VQW 1 "register_operand" "w")
- (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
- (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
- (match_operand:VQW 2 "register_operand" "w")
- (match_dup 3)))))]
- "TARGET_SIMD"
- "<su>mull2\\t%0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_mull")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "vec_widen_<su>mult_hi_<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "")
- (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))
- (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand" ""))]
- "TARGET_SIMD"
- {
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_simd_vec_<su>mult_hi_<mode> (operands[0],
- operands[1],
- operands[2], p));
- DONE;
-
- }
-)
-
-;; FP vector operations.
-;; AArch64 AdvSIMD supports single-precision (32-bit) and
-;; double-precision (64-bit) floating-point data types and arithmetic as
-;; defined by the IEEE 754-2008 standard. This makes them vectorizable
-;; without the need for -ffast-math or -funsafe-math-optimizations.
-;;
-;; Floating-point operations can raise an exception. Vectorizing such
-;; operations are safe because of reasons explained below.
-;;
-;; ARMv8 permits an extension to enable trapped floating-point
-;; exception handling, however this is an optional feature. In the
-;; event of a floating-point exception being raised by vectorised
-;; code then:
-;; 1. If trapped floating-point exceptions are available, then a trap
-;; will be taken when any lane raises an enabled exception. A trap
-;; handler may determine which lane raised the exception.
-;; 2. Alternatively a sticky exception flag is set in the
-;; floating-point status register (FPSR). Software may explicitly
-;; test the exception flags, in which case the tests will either
-;; prevent vectorisation, allowing precise identification of the
-;; failing operation, or if tested outside of vectorisable regions
-;; then the specific operation and lane are not of interest.
-
-;; FP arithmetic operations.
-
-(define_insn "add<mode>3"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (plus:VDQF (match_operand:VDQF 1 "register_operand" "w")
- (match_operand:VDQF 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "fadd\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fadd")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "sub<mode>3"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (minus:VDQF (match_operand:VDQF 1 "register_operand" "w")
- (match_operand:VDQF 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "fsub\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fadd")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "mul<mode>3"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (mult:VDQF (match_operand:VDQF 1 "register_operand" "w")
- (match_operand:VDQF 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "fmul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fmul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "div<mode>3"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (div:VDQF (match_operand:VDQF 1 "register_operand" "w")
- (match_operand:VDQF 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "fdiv\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fdiv")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "neg<mode>2"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (neg:VDQF (match_operand:VDQF 1 "register_operand" "w")))]
- "TARGET_SIMD"
- "fneg\\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_fnegabs")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "abs<mode>2"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (abs:VDQF (match_operand:VDQF 1 "register_operand" "w")))]
- "TARGET_SIMD"
- "fabs\\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_fnegabs")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "fma<mode>4"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (fma:VDQF (match_operand:VDQF 1 "register_operand" "w")
- (match_operand:VDQF 2 "register_operand" "w")
- (match_operand:VDQF 3 "register_operand" "0")))]
- "TARGET_SIMD"
- "fmla\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fmla")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_frint<frint_suffix><mode>"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")]
- FRINT))]
- "TARGET_SIMD"
- "frint<frint_suffix>\\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_frint")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; Vector versions of the floating-point frint patterns.
-;; Expands to btrunc, ceil, floor, nearbyint, rint, round.
-(define_expand "<frint_pattern><mode>2"
- [(set (match_operand:VDQF 0 "register_operand")
- (unspec:VDQF [(match_operand:VDQF 1 "register_operand")]
- FRINT))]
- "TARGET_SIMD"
- {})
-
-(define_insn "aarch64_fcvt<frint_suffix><su><mode>"
- [(set (match_operand:<FCVT_TARGET> 0 "register_operand" "=w")
- (FIXUORS:<FCVT_TARGET> (unspec:<FCVT_TARGET>
- [(match_operand:VDQF 1 "register_operand" "w")]
- FCVT)))]
- "TARGET_SIMD"
- "fcvt<frint_suffix><su>\\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_fcvti")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; Vector versions of the fcvt standard patterns.
-;; Expands to lbtrunc, lround, lceil, lfloor
-(define_expand "l<fcvt_pattern><su_optab><fcvt_target><VDQF:mode>2"
- [(set (match_operand:<FCVT_TARGET> 0 "register_operand")
- (FIXUORS:<FCVT_TARGET> (unspec:<FCVT_TARGET>
- [(match_operand:VDQF 1 "register_operand")]
- FCVT)))]
- "TARGET_SIMD"
- {})
-
-(define_insn "aarch64_vmls<mode>"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (minus:VDQF (match_operand:VDQF 1 "register_operand" "0")
- (mult:VDQF (match_operand:VDQF 2 "register_operand" "w")
- (match_operand:VDQF 3 "register_operand" "w"))))]
- "TARGET_SIMD"
- "fmls\\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
- [(set_attr "simd_type" "simd_fmla")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; FP Max/Min
-;; Max/Min are introduced by idiom recognition by GCC's mid-end. An
-;; expression like:
-;; a = (b < c) ? b : c;
-;; is idiom-matched as MIN_EXPR<b,c> only if -ffinite-math-only is enabled
-;; either explicitly or indirectly via -ffast-math.
-;;
-;; MIN_EXPR and MAX_EXPR eventually map to 'smin' and 'smax' in RTL.
-;; The 'smax' and 'smin' RTL standard pattern names do not specify which
-;; operand will be returned when both operands are zero (i.e. they may not
-;; honour signed zeroes), or when either operand is NaN. Therefore GCC
-;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring
-;; NaNs.
-
-(define_insn "smax<mode>3"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (smax:VDQF (match_operand:VDQF 1 "register_operand" "w")
- (match_operand:VDQF 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "fmaxnm\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fminmax")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "smin<mode>3"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (smin:VDQF (match_operand:VDQF 1 "register_operand" "w")
- (match_operand:VDQF 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "fminnm\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fminmax")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; FP 'across lanes' max and min ops.
-
-(define_insn "reduc_s<fmaxminv>_v4sf"
- [(set (match_operand:V4SF 0 "register_operand" "=w")
- (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")]
- FMAXMINV))]
- "TARGET_SIMD"
- "f<fmaxminv>nmv\\t%s0, %1.4s";
- [(set_attr "simd_type" "simd_fminmaxv")
- (set_attr "simd_mode" "V4SF")]
-)
-
-(define_insn "reduc_s<fmaxminv>_<mode>"
- [(set (match_operand:V2F 0 "register_operand" "=w")
- (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
- FMAXMINV))]
- "TARGET_SIMD"
- "f<fmaxminv>nmp\\t%0.<Vtype>, %1.<Vtype>, %1.<Vtype>";
- [(set_attr "simd_type" "simd_fminmax")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; FP 'across lanes' add.
-
-(define_insn "aarch64_addvv4sf"
- [(set (match_operand:V4SF 0 "register_operand" "=w")
- (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")]
- UNSPEC_FADDV))]
- "TARGET_SIMD"
- "faddp\\t%0.4s, %1.4s, %1.4s"
- [(set_attr "simd_type" "simd_fadd")
- (set_attr "simd_mode" "V4SF")]
-)
-
-(define_expand "reduc_uplus_v4sf"
- [(set (match_operand:V4SF 0 "register_operand" "=w")
- (match_operand:V4SF 1 "register_operand" "w"))]
- "TARGET_SIMD"
-{
- rtx tmp = gen_reg_rtx (V4SFmode);
- emit_insn (gen_aarch64_addvv4sf (tmp, operands[1]));
- emit_insn (gen_aarch64_addvv4sf (operands[0], tmp));
- DONE;
-})
-
-(define_expand "reduc_splus_v4sf"
- [(set (match_operand:V4SF 0 "register_operand" "=w")
- (match_operand:V4SF 1 "register_operand" "w"))]
- "TARGET_SIMD"
-{
- rtx tmp = gen_reg_rtx (V4SFmode);
- emit_insn (gen_aarch64_addvv4sf (tmp, operands[1]));
- emit_insn (gen_aarch64_addvv4sf (operands[0], tmp));
- DONE;
-})
-
-(define_insn "aarch64_addv<mode>"
- [(set (match_operand:V2F 0 "register_operand" "=w")
- (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
- UNSPEC_FADDV))]
- "TARGET_SIMD"
- "faddp\\t%<Vetype>0, %1.<Vtype>"
- [(set_attr "simd_type" "simd_fadd")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "reduc_uplus_<mode>"
- [(set (match_operand:V2F 0 "register_operand" "=w")
- (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
- UNSPEC_FADDV))]
- "TARGET_SIMD"
- ""
-)
-
-(define_expand "reduc_splus_<mode>"
- [(set (match_operand:V2F 0 "register_operand" "=w")
- (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
- UNSPEC_FADDV))]
- "TARGET_SIMD"
- ""
-)
-
-;; Reduction across lanes.
-
-(define_insn "aarch64_addv<mode>"
- [(set (match_operand:VDQV 0 "register_operand" "=w")
- (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
- UNSPEC_ADDV))]
- "TARGET_SIMD"
- "addv\\t%<Vetype>0, %1.<Vtype>"
- [(set_attr "simd_type" "simd_addv")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "reduc_splus_<mode>"
- [(set (match_operand:VDQV 0 "register_operand" "=w")
- (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
- UNSPEC_ADDV))]
- "TARGET_SIMD"
- ""
-)
-
-(define_expand "reduc_uplus_<mode>"
- [(set (match_operand:VDQV 0 "register_operand" "=w")
- (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
- UNSPEC_ADDV))]
- "TARGET_SIMD"
- ""
-)
-
-(define_insn "aarch64_addvv2di"
- [(set (match_operand:V2DI 0 "register_operand" "=w")
- (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")]
- UNSPEC_ADDV))]
- "TARGET_SIMD"
- "addp\\t%d0, %1.2d"
- [(set_attr "simd_type" "simd_add")
- (set_attr "simd_mode" "V2DI")]
-)
-
-(define_expand "reduc_uplus_v2di"
- [(set (match_operand:V2DI 0 "register_operand" "=w")
- (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")]
- UNSPEC_ADDV))]
- "TARGET_SIMD"
- ""
-)
-
-(define_expand "reduc_splus_v2di"
- [(set (match_operand:V2DI 0 "register_operand" "=w")
- (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")]
- UNSPEC_ADDV))]
- "TARGET_SIMD"
- ""
-)
-
-(define_insn "aarch64_addvv2si"
- [(set (match_operand:V2SI 0 "register_operand" "=w")
- (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
- UNSPEC_ADDV))]
- "TARGET_SIMD"
- "addp\\t%0.2s, %1.2s, %1.2s"
- [(set_attr "simd_type" "simd_add")
- (set_attr "simd_mode" "V2SI")]
-)
-
-(define_expand "reduc_uplus_v2si"
- [(set (match_operand:V2SI 0 "register_operand" "=w")
- (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
- UNSPEC_ADDV))]
- "TARGET_SIMD"
- ""
-)
-
-(define_expand "reduc_splus_v2si"
- [(set (match_operand:V2SI 0 "register_operand" "=w")
- (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
- UNSPEC_ADDV))]
- "TARGET_SIMD"
- ""
-)
-
-(define_insn "reduc_<maxminv>_<mode>"
- [(set (match_operand:VDQV 0 "register_operand" "=w")
- (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
- MAXMINV))]
- "TARGET_SIMD"
- "<maxminv>v\\t%<Vetype>0, %1.<Vtype>"
- [(set_attr "simd_type" "simd_minmaxv")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "reduc_<maxminv>_v2si"
- [(set (match_operand:V2SI 0 "register_operand" "=w")
- (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
- MAXMINV))]
- "TARGET_SIMD"
- "<maxminv>p\\t%0.2s, %1.2s, %1.2s"
- [(set_attr "simd_type" "simd_minmax")
- (set_attr "simd_mode" "V2SI")]
-)
-
-;; vbsl_* intrinsics may compile to any of bsl/bif/bit depending on register
-;; allocation. For an intrinsic of form:
-;; vD = bsl_* (vS, vN, vM)
-;; We can use any of:
-;; bsl vS, vN, vM (if D = S)
-;; bit vD, vN, vS (if D = M, so 1-bits in vS choose bits from vN, else vM)
-;; bif vD, vM, vS (if D = N, so 0-bits in vS choose bits from vM, else vN)
-
-(define_insn "aarch64_simd_bsl<mode>_internal"
- [(set (match_operand:VALL 0 "register_operand" "=w,w,w")
- (unspec:VALL
- [(match_operand:<V_cmp_result> 1 "register_operand" " 0,w,w")
- (match_operand:VALL 2 "register_operand" " w,w,0")
- (match_operand:VALL 3 "register_operand" " w,0,w")]
- UNSPEC_BSL))]
- "TARGET_SIMD"
- "@
- bsl\\t%0.<Vbtype>, %2.<Vbtype>, %3.<Vbtype>
- bit\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>
- bif\\t%0.<Vbtype>, %3.<Vbtype>, %1.<Vbtype>"
-)
-
-(define_expand "aarch64_simd_bsl<mode>"
- [(set (match_operand:VALL 0 "register_operand")
- (unspec:VALL [(match_operand:<V_cmp_result> 1 "register_operand")
- (match_operand:VALL 2 "register_operand")
- (match_operand:VALL 3 "register_operand")]
- UNSPEC_BSL))]
- "TARGET_SIMD"
-{
- /* We can't alias operands together if they have different modes. */
- operands[1] = gen_lowpart (<V_cmp_result>mode, operands[1]);
-})
-
-(define_expand "aarch64_vcond_internal<mode>"
- [(set (match_operand:VDQ 0 "register_operand")
- (if_then_else:VDQ
- (match_operator 3 "comparison_operator"
- [(match_operand:VDQ 4 "register_operand")
- (match_operand:VDQ 5 "nonmemory_operand")])
- (match_operand:VDQ 1 "register_operand")
- (match_operand:VDQ 2 "register_operand")))]
- "TARGET_SIMD"
-{
- int inverse = 0, has_zero_imm_form = 0;
- rtx mask = gen_reg_rtx (<MODE>mode);
-
- switch (GET_CODE (operands[3]))
- {
- case LE:
- case LT:
- case NE:
- inverse = 1;
- /* Fall through. */
- case GE:
- case GT:
- case EQ:
- has_zero_imm_form = 1;
- break;
- case LEU:
- case LTU:
- inverse = 1;
- break;
- default:
- break;
- }
-
- if (!REG_P (operands[5])
- && (operands[5] != CONST0_RTX (<MODE>mode) || !has_zero_imm_form))
- operands[5] = force_reg (<MODE>mode, operands[5]);
-
- switch (GET_CODE (operands[3]))
- {
- case LT:
- case GE:
- emit_insn (gen_aarch64_cmge<mode> (mask, operands[4], operands[5]));
- break;
-
- case LE:
- case GT:
- emit_insn (gen_aarch64_cmgt<mode> (mask, operands[4], operands[5]));
- break;
-
- case LTU:
- case GEU:
- emit_insn (gen_aarch64_cmhs<mode> (mask, operands[4], operands[5]));
- break;
-
- case LEU:
- case GTU:
- emit_insn (gen_aarch64_cmhi<mode> (mask, operands[4], operands[5]));
- break;
-
- case NE:
- case EQ:
- emit_insn (gen_aarch64_cmeq<mode> (mask, operands[4], operands[5]));
- break;
-
- default:
- gcc_unreachable ();
- }
-
- if (inverse)
- emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask, operands[2],
- operands[1]));
- else
- emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask, operands[1],
- operands[2]));
-
- DONE;
-})
-
-(define_expand "aarch64_vcond_internal<mode>"
- [(set (match_operand:VDQF 0 "register_operand")
- (if_then_else:VDQF
- (match_operator 3 "comparison_operator"
- [(match_operand:VDQF 4 "register_operand")
- (match_operand:VDQF 5 "nonmemory_operand")])
- (match_operand:VDQF 1 "register_operand")
- (match_operand:VDQF 2 "register_operand")))]
- "TARGET_SIMD"
-{
- int inverse = 0;
- int use_zero_form = 0;
- int swap_bsl_operands = 0;
- rtx mask = gen_reg_rtx (<V_cmp_result>mode);
- rtx tmp = gen_reg_rtx (<V_cmp_result>mode);
-
- rtx (*base_comparison) (rtx, rtx, rtx);
- rtx (*complimentary_comparison) (rtx, rtx, rtx);
-
- switch (GET_CODE (operands[3]))
- {
- case GE:
- case GT:
- case LE:
- case LT:
- case EQ:
- if (operands[5] == CONST0_RTX (<MODE>mode))
- {
- use_zero_form = 1;
- break;
- }
- /* Fall through. */
- default:
- if (!REG_P (operands[5]))
- operands[5] = force_reg (<MODE>mode, operands[5]);
- }
-
- switch (GET_CODE (operands[3]))
- {
- case LT:
- case UNLT:
- inverse = 1;
- /* Fall through. */
- case GE:
- case UNGE:
- case ORDERED:
- case UNORDERED:
- base_comparison = gen_aarch64_cmge<mode>;
- complimentary_comparison = gen_aarch64_cmgt<mode>;
- break;
- case LE:
- case UNLE:
- inverse = 1;
- /* Fall through. */
- case GT:
- case UNGT:
- base_comparison = gen_aarch64_cmgt<mode>;
- complimentary_comparison = gen_aarch64_cmge<mode>;
- break;
- case EQ:
- case NE:
- case UNEQ:
- base_comparison = gen_aarch64_cmeq<mode>;
- complimentary_comparison = gen_aarch64_cmeq<mode>;
- break;
- default:
- gcc_unreachable ();
- }
-
- switch (GET_CODE (operands[3]))
- {
- case LT:
- case LE:
- case GT:
- case GE:
- case EQ:
- /* The easy case. Here we emit one of FCMGE, FCMGT or FCMEQ.
- As a LT b <=> b GE a && a LE b <=> b GT a. Our transformations are:
- a GE b -> a GE b
- a GT b -> a GT b
- a LE b -> b GE a
- a LT b -> b GT a
- a EQ b -> a EQ b
- Note that there also exist direct comparison against 0 forms,
- so catch those as a special case. */
- if (use_zero_form)
- {
- inverse = 0;
- switch (GET_CODE (operands[3]))
- {
- case LT:
- base_comparison = gen_aarch64_cmlt<mode>;
- break;
- case LE:
- base_comparison = gen_aarch64_cmle<mode>;
- break;
- default:
- /* Do nothing, other zero form cases already have the correct
- base_comparison. */
- break;
- }
- }
-
- if (!inverse)
- emit_insn (base_comparison (mask, operands[4], operands[5]));
- else
- emit_insn (complimentary_comparison (mask, operands[5], operands[4]));
- break;
- case UNLT:
- case UNLE:
- case UNGT:
- case UNGE:
- case NE:
- /* FCM returns false for lanes which are unordered, so if we use
- the inverse of the comparison we actually want to emit, then
- swap the operands to BSL, we will end up with the correct result.
- Note that a NE NaN and NaN NE b are true for all a, b.
-
- Our transformations are:
- a GE b -> !(b GT a)
- a GT b -> !(b GE a)
- a LE b -> !(a GT b)
- a LT b -> !(a GE b)
- a NE b -> !(a EQ b) */
-
- if (inverse)
- emit_insn (base_comparison (mask, operands[4], operands[5]));
- else
- emit_insn (complimentary_comparison (mask, operands[5], operands[4]));
-
- swap_bsl_operands = 1;
- break;
- case UNEQ:
- /* We check (a > b || b > a). combining these comparisons give us
- true iff !(a != b && a ORDERED b), swapping the operands to BSL
- will then give us (a == b || a UNORDERED b) as intended. */
-
- emit_insn (gen_aarch64_cmgt<mode> (mask, operands[4], operands[5]));
- emit_insn (gen_aarch64_cmgt<mode> (tmp, operands[5], operands[4]));
- emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
- swap_bsl_operands = 1;
- break;
- case UNORDERED:
- /* Operands are ORDERED iff (a > b || b >= a).
- Swapping the operands to BSL will give the UNORDERED case. */
- swap_bsl_operands = 1;
- /* Fall through. */
- case ORDERED:
- emit_insn (gen_aarch64_cmgt<mode> (tmp, operands[4], operands[5]));
- emit_insn (gen_aarch64_cmge<mode> (mask, operands[5], operands[4]));
- emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
- break;
- default:
- gcc_unreachable ();
- }
-
- if (swap_bsl_operands)
- emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask, operands[2],
- operands[1]));
- else
- emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], mask, operands[1],
- operands[2]));
- DONE;
-})
-
-(define_expand "vcond<mode><mode>"
- [(set (match_operand:VALL 0 "register_operand")
- (if_then_else:VALL
- (match_operator 3 "comparison_operator"
- [(match_operand:VALL 4 "register_operand")
- (match_operand:VALL 5 "nonmemory_operand")])
- (match_operand:VALL 1 "register_operand")
- (match_operand:VALL 2 "register_operand")))]
- "TARGET_SIMD"
-{
- emit_insn (gen_aarch64_vcond_internal<mode> (operands[0], operands[1],
- operands[2], operands[3],
- operands[4], operands[5]));
- DONE;
-})
-
-
-(define_expand "vcondu<mode><mode>"
- [(set (match_operand:VDQ 0 "register_operand")
- (if_then_else:VDQ
- (match_operator 3 "comparison_operator"
- [(match_operand:VDQ 4 "register_operand")
- (match_operand:VDQ 5 "nonmemory_operand")])
- (match_operand:VDQ 1 "register_operand")
- (match_operand:VDQ 2 "register_operand")))]
- "TARGET_SIMD"
-{
- emit_insn (gen_aarch64_vcond_internal<mode> (operands[0], operands[1],
- operands[2], operands[3],
- operands[4], operands[5]));
- DONE;
-})
-
-;; Patterns for AArch64 SIMD Intrinsics.
-
-(define_expand "aarch64_create<mode>"
- [(match_operand:VD_RE 0 "register_operand" "")
- (match_operand:DI 1 "general_operand" "")]
- "TARGET_SIMD"
-{
- rtx src = gen_lowpart (<MODE>mode, operands[1]);
- emit_move_insn (operands[0], src);
- DONE;
-})
-
-(define_insn "aarch64_get_lane_signed<mode>"
- [(set (match_operand:<VEL> 0 "register_operand" "=r")
- (sign_extend:<VEL>
- (vec_select:<VEL>
- (match_operand:VQ_S 1 "register_operand" "w")
- (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
- "TARGET_SIMD"
- "smov\\t%0, %1.<Vetype>[%2]"
- [(set_attr "simd_type" "simd_movgp")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_get_lane_unsigned<mode>"
- [(set (match_operand:<VEL> 0 "register_operand" "=r")
- (zero_extend:<VEL>
- (vec_select:<VEL>
- (match_operand:VDQ 1 "register_operand" "w")
- (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
- "TARGET_SIMD"
- "umov\\t%<vw>0, %1.<Vetype>[%2]"
- [(set_attr "simd_type" "simd_movgp")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_get_lane<mode>"
- [(set (match_operand:<VEL> 0 "register_operand" "=w")
- (vec_select:<VEL>
- (match_operand:VDQF 1 "register_operand" "w")
- (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
- "TARGET_SIMD"
- "mov\\t%0.<Vetype>[0], %1.<Vetype>[%2]"
- [(set_attr "simd_type" "simd_ins")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "aarch64_get_lanedi"
- [(match_operand:DI 0 "register_operand" "=r")
- (match_operand:DI 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- aarch64_simd_lane_bounds (operands[2], 0, 1);
- emit_move_insn (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "aarch64_reinterpretv8qi<mode>"
- [(match_operand:V8QI 0 "register_operand" "")
- (match_operand:VDC 1 "register_operand" "")]
- "TARGET_SIMD"
-{
- aarch64_simd_reinterpret (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "aarch64_reinterpretv4hi<mode>"
- [(match_operand:V4HI 0 "register_operand" "")
- (match_operand:VDC 1 "register_operand" "")]
- "TARGET_SIMD"
-{
- aarch64_simd_reinterpret (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "aarch64_reinterpretv2si<mode>"
- [(match_operand:V2SI 0 "register_operand" "")
- (match_operand:VDC 1 "register_operand" "")]
- "TARGET_SIMD"
-{
- aarch64_simd_reinterpret (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "aarch64_reinterpretv2sf<mode>"
- [(match_operand:V2SF 0 "register_operand" "")
- (match_operand:VDC 1 "register_operand" "")]
- "TARGET_SIMD"
-{
- aarch64_simd_reinterpret (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "aarch64_reinterpretdi<mode>"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:VD_RE 1 "register_operand" "")]
- "TARGET_SIMD"
-{
- aarch64_simd_reinterpret (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "aarch64_reinterpretv16qi<mode>"
- [(match_operand:V16QI 0 "register_operand" "")
- (match_operand:VQ 1 "register_operand" "")]
- "TARGET_SIMD"
-{
- aarch64_simd_reinterpret (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "aarch64_reinterpretv8hi<mode>"
- [(match_operand:V8HI 0 "register_operand" "")
- (match_operand:VQ 1 "register_operand" "")]
- "TARGET_SIMD"
-{
- aarch64_simd_reinterpret (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "aarch64_reinterpretv4si<mode>"
- [(match_operand:V4SI 0 "register_operand" "")
- (match_operand:VQ 1 "register_operand" "")]
- "TARGET_SIMD"
-{
- aarch64_simd_reinterpret (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "aarch64_reinterpretv4sf<mode>"
- [(match_operand:V4SF 0 "register_operand" "")
- (match_operand:VQ 1 "register_operand" "")]
- "TARGET_SIMD"
-{
- aarch64_simd_reinterpret (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "aarch64_reinterpretv2di<mode>"
- [(match_operand:V2DI 0 "register_operand" "")
- (match_operand:VQ 1 "register_operand" "")]
- "TARGET_SIMD"
-{
- aarch64_simd_reinterpret (operands[0], operands[1]);
- DONE;
-})
-
-(define_expand "aarch64_reinterpretv2df<mode>"
- [(match_operand:V2DF 0 "register_operand" "")
- (match_operand:VQ 1 "register_operand" "")]
- "TARGET_SIMD"
-{
- aarch64_simd_reinterpret (operands[0], operands[1]);
- DONE;
-})
-
-;; In this insn, operand 1 should be low, and operand 2 the high part of the
-;; dest vector.
-
-(define_insn "*aarch64_combinez<mode>"
- [(set (match_operand:<VDBL> 0 "register_operand" "=&w")
- (vec_concat:<VDBL>
- (match_operand:VDIC 1 "register_operand" "w")
- (match_operand:VDIC 2 "aarch64_simd_imm_zero" "Dz")))]
- "TARGET_SIMD"
- "mov\\t%0.8b, %1.8b"
- [(set_attr "simd_type" "simd_move")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_combine<mode>"
- [(set (match_operand:<VDBL> 0 "register_operand" "=&w")
- (vec_concat:<VDBL> (match_operand:VDC 1 "register_operand" "w")
- (match_operand:VDC 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "mov\\t%0.d[0], %1.d[0]\;ins\\t%0.d[1], %2.d[0]"
- [(set_attr "simd_type" "simd_ins")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; <su><addsub>l<q>.
-
-(define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l2<mode>_internal"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (ADDSUB:<VWIDE> (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
- (match_operand:VQW 1 "register_operand" "w")
- (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))
- (ANY_EXTEND:<VWIDE> (vec_select:<VHALF>
- (match_operand:VQW 2 "register_operand" "w")
- (match_dup 3)))))]
- "TARGET_SIMD"
- "<ANY_EXTEND:su><ADDSUB:optab>l2 %0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_addl")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "aarch64_saddl2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQW 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_saddl2<mode>_internal (operands[0], operands[1],
- operands[2], p));
- DONE;
-})
-
-(define_expand "aarch64_uaddl2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQW 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_uaddl2<mode>_internal (operands[0], operands[1],
- operands[2], p));
- DONE;
-})
-
-(define_expand "aarch64_ssubl2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQW 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_ssubl2<mode>_internal (operands[0], operands[1],
- operands[2], p));
- DONE;
-})
-
-(define_expand "aarch64_usubl2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQW 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_usubl2<mode>_internal (operands[0], operands[1],
- operands[2], p));
- DONE;
-})
-
-(define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>l<mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (ADDSUB:<VWIDE> (ANY_EXTEND:<VWIDE>
- (match_operand:VDW 1 "register_operand" "w"))
- (ANY_EXTEND:<VWIDE>
- (match_operand:VDW 2 "register_operand" "w"))))]
- "TARGET_SIMD"
- "<ANY_EXTEND:su><ADDSUB:optab>l %0.<Vwtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_addl")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; <su><addsub>w<q>.
-
-(define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>w<mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (ADDSUB:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "w")
- (ANY_EXTEND:<VWIDE>
- (match_operand:VDW 2 "register_operand" "w"))))]
- "TARGET_SIMD"
- "<ANY_EXTEND:su><ADDSUB:optab>w\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_addl")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_<ANY_EXTEND:su><ADDSUB:optab>w2<mode>_internal"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (ADDSUB:<VWIDE> (match_operand:<VWIDE> 1 "register_operand" "w")
- (ANY_EXTEND:<VWIDE>
- (vec_select:<VHALF>
- (match_operand:VQW 2 "register_operand" "w")
- (match_operand:VQW 3 "vect_par_cnst_hi_half" "")))))]
- "TARGET_SIMD"
- "<ANY_EXTEND:su><ADDSUB:optab>w2\\t%0.<Vwtype>, %1.<Vwtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_addl")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "aarch64_saddw2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_saddw2<mode>_internal (operands[0], operands[1],
- operands[2], p));
- DONE;
-})
-
-(define_expand "aarch64_uaddw2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_uaddw2<mode>_internal (operands[0], operands[1],
- operands[2], p));
- DONE;
-})
-
-
-(define_expand "aarch64_ssubw2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_ssubw2<mode>_internal (operands[0], operands[1],
- operands[2], p));
- DONE;
-})
-
-(define_expand "aarch64_usubw2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_usubw2<mode>_internal (operands[0], operands[1],
- operands[2], p));
- DONE;
-})
-
-;; <su><r>h<addsub>.
-
-(define_insn "aarch64_<sur>h<addsub><mode>"
- [(set (match_operand:VQ_S 0 "register_operand" "=w")
- (unspec:VQ_S [(match_operand:VQ_S 1 "register_operand" "w")
- (match_operand:VQ_S 2 "register_operand" "w")]
- HADDSUB))]
- "TARGET_SIMD"
- "<sur>h<addsub>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_add")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; <r><addsub>hn<q>.
-
-(define_insn "aarch64_<sur><addsub>hn<mode>"
- [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
- (unspec:<VNARROWQ> [(match_operand:VQN 1 "register_operand" "w")
- (match_operand:VQN 2 "register_operand" "w")]
- ADDSUBHN))]
- "TARGET_SIMD"
- "<sur><addsub>hn\\t%0.<Vntype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_addn")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_<sur><addsub>hn2<mode>"
- [(set (match_operand:<VNARROWQ2> 0 "register_operand" "=w")
- (unspec:<VNARROWQ2> [(match_operand:<VNARROWQ> 1 "register_operand" "0")
- (match_operand:VQN 2 "register_operand" "w")
- (match_operand:VQN 3 "register_operand" "w")]
- ADDSUBHN2))]
- "TARGET_SIMD"
- "<sur><addsub>hn2\\t%0.<V2ntype>, %2.<Vtype>, %3.<Vtype>"
- [(set_attr "simd_type" "simd_addn2")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; pmul.
-
-(define_insn "aarch64_pmul<mode>"
- [(set (match_operand:VB 0 "register_operand" "=w")
- (unspec:VB [(match_operand:VB 1 "register_operand" "w")
- (match_operand:VB 2 "register_operand" "w")]
- UNSPEC_PMUL))]
- "TARGET_SIMD"
- "pmul\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_mul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; <su>q<addsub>
-
-(define_insn "aarch64_<su_optab><optab><mode>"
- [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
- (BINQOPS:VSDQ_I (match_operand:VSDQ_I 1 "register_operand" "w")
- (match_operand:VSDQ_I 2 "register_operand" "w")))]
- "TARGET_SIMD"
- "<su_optab><optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_add")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; suqadd and usqadd
-
-(define_insn "aarch64_<sur>qadd<mode>"
- [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
- (unspec:VSDQ_I [(match_operand:VSDQ_I 1 "register_operand" "0")
- (match_operand:VSDQ_I 2 "register_operand" "w")]
- USSUQADD))]
- "TARGET_SIMD"
- "<sur>qadd\\t%<v>0<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_sat_add")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; sqmovun
-
-(define_insn "aarch64_sqmovun<mode>"
- [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
- (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")]
- UNSPEC_SQXTUN))]
- "TARGET_SIMD"
- "sqxtun\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
- [(set_attr "simd_type" "simd_sat_shiftn_imm")
- (set_attr "simd_mode" "<MODE>")]
- )
-
-;; sqmovn and uqmovn
-
-(define_insn "aarch64_<sur>qmovn<mode>"
- [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
- (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")]
- SUQMOVN))]
- "TARGET_SIMD"
- "<sur>qxtn\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>"
- [(set_attr "simd_type" "simd_sat_shiftn_imm")
- (set_attr "simd_mode" "<MODE>")]
- )
-
-;; <su>q<absneg>
-
-(define_insn "aarch64_s<optab><mode>"
- [(set (match_operand:VSDQ_I_BHSI 0 "register_operand" "=w")
- (UNQOPS:VSDQ_I_BHSI
- (match_operand:VSDQ_I_BHSI 1 "register_operand" "w")))]
- "TARGET_SIMD"
- "s<optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>"
- [(set_attr "simd_type" "simd_sat_negabs")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; sq<r>dmulh.
-
-(define_insn "aarch64_sq<r>dmulh<mode>"
- [(set (match_operand:VSDQ_HSI 0 "register_operand" "=w")
- (unspec:VSDQ_HSI
- [(match_operand:VSDQ_HSI 1 "register_operand" "w")
- (match_operand:VSDQ_HSI 2 "register_operand" "w")]
- VQDMULH))]
- "TARGET_SIMD"
- "sq<r>dmulh\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; sq<r>dmulh_lane
-
-(define_insn "aarch64_sq<r>dmulh_lane<mode>"
- [(set (match_operand:VDQHS 0 "register_operand" "=w")
- (unspec:VDQHS
- [(match_operand:VDQHS 1 "register_operand" "w")
- (vec_select:<VEL>
- (match_operand:<VCOND> 2 "register_operand" "<vwx>")
- (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
- VQDMULH))]
- "TARGET_SIMD"
- "*
- aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCOND>mode));
- return \"sq<r>dmulh\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]\";"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_sq<r>dmulh_laneq<mode>"
- [(set (match_operand:VDQHS 0 "register_operand" "=w")
- (unspec:VDQHS
- [(match_operand:VDQHS 1 "register_operand" "w")
- (vec_select:<VEL>
- (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
- (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
- VQDMULH))]
- "TARGET_SIMD"
- "*
- aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
- return \"sq<r>dmulh\\t%0.<Vtype>, %1.<Vtype>, %2.<Vetype>[%3]\";"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_sq<r>dmulh_lane<mode>"
- [(set (match_operand:SD_HSI 0 "register_operand" "=w")
- (unspec:SD_HSI
- [(match_operand:SD_HSI 1 "register_operand" "w")
- (vec_select:<VEL>
- (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
- (parallel [(match_operand:SI 3 "immediate_operand" "i")]))]
- VQDMULH))]
- "TARGET_SIMD"
- "*
- aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCONQ>mode));
- return \"sq<r>dmulh\\t%<v>0, %<v>1, %2.<v>[%3]\";"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; vqdml[sa]l
-
-(define_insn "aarch64_sqdml<SBINQOPS:as>l<mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (SBINQOPS:<VWIDE>
- (match_operand:<VWIDE> 1 "register_operand" "0")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (match_operand:VSD_HSI 2 "register_operand" "w"))
- (sign_extend:<VWIDE>
- (match_operand:VSD_HSI 3 "register_operand" "w")))
- (const_int 1))))]
- "TARGET_SIMD"
- "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %<v>3<Vmtype>"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; vqdml[sa]l_lane
-
-(define_insn "aarch64_sqdml<SBINQOPS:as>l_lane<mode>_internal"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (SBINQOPS:<VWIDE>
- (match_operand:<VWIDE> 1 "register_operand" "0")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (match_operand:VD_HSI 2 "register_operand" "w"))
- (sign_extend:<VWIDE>
- (vec_duplicate:VD_HSI
- (vec_select:<VEL>
- (match_operand:<VCON> 3 "register_operand" "<vwx>")
- (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
- ))
- (const_int 1))))]
- "TARGET_SIMD"
- "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_sqdml<SBINQOPS:as>l_lane<mode>_internal"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (SBINQOPS:<VWIDE>
- (match_operand:<VWIDE> 1 "register_operand" "0")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (match_operand:SD_HSI 2 "register_operand" "w"))
- (sign_extend:<VWIDE>
- (vec_select:<VEL>
- (match_operand:<VCON> 3 "register_operand" "<vwx>")
- (parallel [(match_operand:SI 4 "immediate_operand" "i")])))
- )
- (const_int 1))))]
- "TARGET_SIMD"
- "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "aarch64_sqdmlal_lane<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "0")
- (match_operand:VSD_HSI 2 "register_operand" "w")
- (match_operand:<VCON> 3 "register_operand" "<vwx>")
- (match_operand:SI 4 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCON>mode) / 2);
- emit_insn (gen_aarch64_sqdmlal_lane<mode>_internal (operands[0], operands[1],
- operands[2], operands[3],
- operands[4]));
- DONE;
-})
-
-(define_expand "aarch64_sqdmlal_laneq<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "0")
- (match_operand:VSD_HSI 2 "register_operand" "w")
- (match_operand:<VCON> 3 "register_operand" "<vwx>")
- (match_operand:SI 4 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCON>mode));
- emit_insn (gen_aarch64_sqdmlal_lane<mode>_internal (operands[0], operands[1],
- operands[2], operands[3],
- operands[4]));
- DONE;
-})
-
-(define_expand "aarch64_sqdmlsl_lane<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "0")
- (match_operand:VSD_HSI 2 "register_operand" "w")
- (match_operand:<VCON> 3 "register_operand" "<vwx>")
- (match_operand:SI 4 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCON>mode) / 2);
- emit_insn (gen_aarch64_sqdmlsl_lane<mode>_internal (operands[0], operands[1],
- operands[2], operands[3],
- operands[4]));
- DONE;
-})
-
-(define_expand "aarch64_sqdmlsl_laneq<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "0")
- (match_operand:VSD_HSI 2 "register_operand" "w")
- (match_operand:<VCON> 3 "register_operand" "<vwx>")
- (match_operand:SI 4 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<VCON>mode));
- emit_insn (gen_aarch64_sqdmlsl_lane<mode>_internal (operands[0], operands[1],
- operands[2], operands[3],
- operands[4]));
- DONE;
-})
-
-;; vqdml[sa]l_n
-
-(define_insn "aarch64_sqdml<SBINQOPS:as>l_n<mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (SBINQOPS:<VWIDE>
- (match_operand:<VWIDE> 1 "register_operand" "0")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (match_operand:VD_HSI 2 "register_operand" "w"))
- (sign_extend:<VWIDE>
- (vec_duplicate:VD_HSI
- (match_operand:<VEL> 3 "register_operand" "w"))))
- (const_int 1))))]
- "TARGET_SIMD"
- "sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; sqdml[as]l2
-
-(define_insn "aarch64_sqdml<SBINQOPS:as>l2<mode>_internal"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (SBINQOPS:<VWIDE>
- (match_operand:<VWIDE> 1 "register_operand" "0")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (vec_select:<VHALF>
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
- (sign_extend:<VWIDE>
- (vec_select:<VHALF>
- (match_operand:VQ_HSI 3 "register_operand" "w")
- (match_dup 4))))
- (const_int 1))))]
- "TARGET_SIMD"
- "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %<v>3<Vmtype>"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "aarch64_sqdmlal2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:VQ_HSI 3 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_sqdmlal2<mode>_internal (operands[0], operands[1],
- operands[2], operands[3], p));
- DONE;
-})
-
-(define_expand "aarch64_sqdmlsl2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:VQ_HSI 3 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_sqdmlsl2<mode>_internal (operands[0], operands[1],
- operands[2], operands[3], p));
- DONE;
-})
-
-;; vqdml[sa]l2_lane
-
-(define_insn "aarch64_sqdml<SBINQOPS:as>l2_lane<mode>_internal"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (SBINQOPS:<VWIDE>
- (match_operand:<VWIDE> 1 "register_operand" "0")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (vec_select:<VHALF>
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:VQ_HSI 5 "vect_par_cnst_hi_half" "")))
- (sign_extend:<VWIDE>
- (vec_duplicate:<VHALF>
- (vec_select:<VEL>
- (match_operand:<VCON> 3 "register_operand" "<vwx>")
- (parallel [(match_operand:SI 4 "immediate_operand" "i")])
- ))))
- (const_int 1))))]
- "TARGET_SIMD"
- "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[%4]"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "aarch64_sqdmlal2_lane<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:<VCON> 3 "register_operand" "<vwx>")
- (match_operand:SI 4 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode) / 2);
- emit_insn (gen_aarch64_sqdmlal2_lane<mode>_internal (operands[0], operands[1],
- operands[2], operands[3],
- operands[4], p));
- DONE;
-})
-
-(define_expand "aarch64_sqdmlal2_laneq<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:<VCON> 3 "register_operand" "<vwx>")
- (match_operand:SI 4 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
- emit_insn (gen_aarch64_sqdmlal2_lane<mode>_internal (operands[0], operands[1],
- operands[2], operands[3],
- operands[4], p));
- DONE;
-})
-
-(define_expand "aarch64_sqdmlsl2_lane<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:<VCON> 3 "register_operand" "<vwx>")
- (match_operand:SI 4 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode) / 2);
- emit_insn (gen_aarch64_sqdmlsl2_lane<mode>_internal (operands[0], operands[1],
- operands[2], operands[3],
- operands[4], p));
- DONE;
-})
-
-(define_expand "aarch64_sqdmlsl2_laneq<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:<VCON> 3 "register_operand" "<vwx>")
- (match_operand:SI 4 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- aarch64_simd_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
- emit_insn (gen_aarch64_sqdmlsl2_lane<mode>_internal (operands[0], operands[1],
- operands[2], operands[3],
- operands[4], p));
- DONE;
-})
-
-(define_insn "aarch64_sqdml<SBINQOPS:as>l2_n<mode>_internal"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (SBINQOPS:<VWIDE>
- (match_operand:<VWIDE> 1 "register_operand" "0")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (vec_select:<VHALF>
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
- (sign_extend:<VWIDE>
- (vec_duplicate:<VHALF>
- (match_operand:<VEL> 3 "register_operand" "w"))))
- (const_int 1))))]
- "TARGET_SIMD"
- "sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
- [(set_attr "simd_type" "simd_sat_mlal")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "aarch64_sqdmlal2_n<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:<VEL> 3 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_sqdmlal2_n<mode>_internal (operands[0], operands[1],
- operands[2], operands[3],
- p));
- DONE;
-})
-
-(define_expand "aarch64_sqdmlsl2_n<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:<VEL> 3 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_sqdmlsl2_n<mode>_internal (operands[0], operands[1],
- operands[2], operands[3],
- p));
- DONE;
-})
-
-;; vqdmull
-
-(define_insn "aarch64_sqdmull<mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (match_operand:VSD_HSI 1 "register_operand" "w"))
- (sign_extend:<VWIDE>
- (match_operand:VSD_HSI 2 "register_operand" "w")))
- (const_int 1)))]
- "TARGET_SIMD"
- "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; vqdmull_lane
-
-(define_insn "aarch64_sqdmull_lane<mode>_internal"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (match_operand:VD_HSI 1 "register_operand" "w"))
- (sign_extend:<VWIDE>
- (vec_duplicate:VD_HSI
- (vec_select:<VEL>
- (match_operand:<VCON> 2 "register_operand" "<vwx>")
- (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
- ))
- (const_int 1)))]
- "TARGET_SIMD"
- "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_sqdmull_lane<mode>_internal"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (match_operand:SD_HSI 1 "register_operand" "w"))
- (sign_extend:<VWIDE>
- (vec_select:<VEL>
- (match_operand:<VCON> 2 "register_operand" "<vwx>")
- (parallel [(match_operand:SI 3 "immediate_operand" "i")]))
- ))
- (const_int 1)))]
- "TARGET_SIMD"
- "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "aarch64_sqdmull_lane<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VSD_HSI 1 "register_operand" "w")
- (match_operand:<VCON> 2 "register_operand" "<vwx>")
- (match_operand:SI 3 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCON>mode) / 2);
- emit_insn (gen_aarch64_sqdmull_lane<mode>_internal (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
-})
-
-(define_expand "aarch64_sqdmull_laneq<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VD_HSI 1 "register_operand" "w")
- (match_operand:<VCON> 2 "register_operand" "<vwx>")
- (match_operand:SI 3 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<VCON>mode));
- emit_insn (gen_aarch64_sqdmull_lane<mode>_internal
- (operands[0], operands[1], operands[2], operands[3]));
- DONE;
-})
-
-;; vqdmull_n
-
-(define_insn "aarch64_sqdmull_n<mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (match_operand:VD_HSI 1 "register_operand" "w"))
- (sign_extend:<VWIDE>
- (vec_duplicate:VD_HSI
- (match_operand:<VEL> 2 "register_operand" "w")))
- )
- (const_int 1)))]
- "TARGET_SIMD"
- "sqdmull\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[0]"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; vqdmull2
-
-
-
-(define_insn "aarch64_sqdmull2<mode>_internal"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (vec_select:<VHALF>
- (match_operand:VQ_HSI 1 "register_operand" "w")
- (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
- (sign_extend:<VWIDE>
- (vec_select:<VHALF>
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_dup 3)))
- )
- (const_int 1)))]
- "TARGET_SIMD"
- "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "aarch64_sqdmull2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQ_HSI 1 "register_operand" "w")
- (match_operand:<VCON> 2 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_sqdmull2<mode>_internal (operands[0], operands[1],
- operands[2], p));
- DONE;
-})
-
-;; vqdmull2_lane
-
-(define_insn "aarch64_sqdmull2_lane<mode>_internal"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (vec_select:<VHALF>
- (match_operand:VQ_HSI 1 "register_operand" "w")
- (match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
- (sign_extend:<VWIDE>
- (vec_duplicate:<VHALF>
- (vec_select:<VEL>
- (match_operand:<VCON> 2 "register_operand" "<vwx>")
- (parallel [(match_operand:SI 3 "immediate_operand" "i")])))
- ))
- (const_int 1)))]
- "TARGET_SIMD"
- "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[%3]"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "aarch64_sqdmull2_lane<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQ_HSI 1 "register_operand" "w")
- (match_operand:<VCON> 2 "register_operand" "<vwx>")
- (match_operand:SI 3 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode) / 2);
- emit_insn (gen_aarch64_sqdmull2_lane<mode>_internal (operands[0], operands[1],
- operands[2], operands[3],
- p));
- DONE;
-})
-
-(define_expand "aarch64_sqdmull2_laneq<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQ_HSI 1 "register_operand" "w")
- (match_operand:<VCON> 2 "register_operand" "<vwx>")
- (match_operand:SI 3 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- aarch64_simd_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
- emit_insn (gen_aarch64_sqdmull2_lane<mode>_internal (operands[0], operands[1],
- operands[2], operands[3],
- p));
- DONE;
-})
-
-;; vqdmull2_n
-
-(define_insn "aarch64_sqdmull2_n<mode>_internal"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (ss_ashift:<VWIDE>
- (mult:<VWIDE>
- (sign_extend:<VWIDE>
- (vec_select:<VHALF>
- (match_operand:VQ_HSI 1 "register_operand" "w")
- (match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
- (sign_extend:<VWIDE>
- (vec_duplicate:<VHALF>
- (match_operand:<VEL> 2 "register_operand" "w")))
- )
- (const_int 1)))]
- "TARGET_SIMD"
- "sqdmull2\\t%<vw2>0<Vmwtype>, %<v>1<Vmtype>, %2.<Vetype>[0]"
- [(set_attr "simd_type" "simd_sat_mul")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "aarch64_sqdmull2_n<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQ_HSI 1 "register_operand" "w")
- (match_operand:<VEL> 2 "register_operand" "w")]
- "TARGET_SIMD"
-{
- rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, true);
- emit_insn (gen_aarch64_sqdmull2_n<mode>_internal (operands[0], operands[1],
- operands[2], p));
- DONE;
-})
-
-;; vshl
-
-(define_insn "aarch64_<sur>shl<mode>"
- [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
- (unspec:VSDQ_I_DI
- [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
- (match_operand:VSDQ_I_DI 2 "register_operand" "w")]
- VSHL))]
- "TARGET_SIMD"
- "<sur>shl\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>";
- [(set_attr "simd_type" "simd_shift")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-
-;; vqshl
-
-(define_insn "aarch64_<sur>q<r>shl<mode>"
- [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
- (unspec:VSDQ_I
- [(match_operand:VSDQ_I 1 "register_operand" "w")
- (match_operand:VSDQ_I 2 "register_operand" "w")]
- VQSHL))]
- "TARGET_SIMD"
- "<sur>q<r>shl\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>";
- [(set_attr "simd_type" "simd_sat_shift")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; vshl_n
-
-(define_expand "aarch64_sshl_n<mode>"
- [(match_operand:VSDQ_I_DI 0 "register_operand" "=w")
- (match_operand:VSDQ_I_DI 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- emit_insn (gen_ashl<mode>3 (operands[0], operands[1], operands[2]));
- DONE;
-})
-
-(define_expand "aarch64_ushl_n<mode>"
- [(match_operand:VSDQ_I_DI 0 "register_operand" "=w")
- (match_operand:VSDQ_I_DI 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- emit_insn (gen_ashl<mode>3 (operands[0], operands[1], operands[2]));
- DONE;
-})
-
-;; vshll_n
-
-(define_insn "aarch64_<sur>shll_n<mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (unspec:<VWIDE> [(match_operand:VDW 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
- VSHLL))]
- "TARGET_SIMD"
- "*
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[2], 0, bit_width + 1);
- if (INTVAL (operands[2]) == bit_width)
- {
- return \"shll\\t%0.<Vwtype>, %1.<Vtype>, %2\";
- }
- else {
- return \"<sur>shll\\t%0.<Vwtype>, %1.<Vtype>, %2\";
- }"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; vshll_high_n
-
-(define_insn "aarch64_<sur>shll2_n<mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (unspec:<VWIDE> [(match_operand:VQW 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
- VSHLL))]
- "TARGET_SIMD"
- "*
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[2], 0, bit_width + 1);
- if (INTVAL (operands[2]) == bit_width)
- {
- return \"shll2\\t%0.<Vwtype>, %1.<Vtype>, %2\";
- }
- else {
- return \"<sur>shll2\\t%0.<Vwtype>, %1.<Vtype>, %2\";
- }"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; vshr_n
-
-(define_expand "aarch64_sshr_n<mode>"
- [(match_operand:VSDQ_I_DI 0 "register_operand" "=w")
- (match_operand:VSDQ_I_DI 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- emit_insn (gen_ashr<mode>3 (operands[0], operands[1], operands[2]));
- DONE;
-})
-
-(define_expand "aarch64_ushr_n<mode>"
- [(match_operand:VSDQ_I_DI 0 "register_operand" "=w")
- (match_operand:VSDQ_I_DI 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- emit_insn (gen_lshr<mode>3 (operands[0], operands[1], operands[2]));
- DONE;
-})
-
-;; vrshr_n
-
-(define_insn "aarch64_<sur>shr_n<mode>"
- [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
- (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
- VRSHR_N))]
- "TARGET_SIMD"
- "*
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[2], 1, bit_width + 1);
- return \"<sur>shr\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2\";"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; v(r)sra_n
-
-(define_insn "aarch64_<sur>sra_n<mode>"
- [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
- (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "0")
- (match_operand:VSDQ_I_DI 2 "register_operand" "w")
- (match_operand:SI 3 "immediate_operand" "i")]
- VSRA))]
- "TARGET_SIMD"
- "*
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[3], 1, bit_width + 1);
- return \"<sur>sra\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3\";"
- [(set_attr "simd_type" "simd_shift_imm_acc")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; vs<lr>i_n
-
-(define_insn "aarch64_<sur>s<lr>i_n<mode>"
- [(set (match_operand:VSDQ_I_DI 0 "register_operand" "=w")
- (unspec:VSDQ_I_DI [(match_operand:VSDQ_I_DI 1 "register_operand" "0")
- (match_operand:VSDQ_I_DI 2 "register_operand" "w")
- (match_operand:SI 3 "immediate_operand" "i")]
- VSLRI))]
- "TARGET_SIMD"
- "*
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[3], 1 - <VSLRI:offsetlr>,
- bit_width - <VSLRI:offsetlr> + 1);
- return \"s<lr>i\\t%<v>0<Vmtype>, %<v>2<Vmtype>, %3\";"
- [(set_attr "simd_type" "simd_shift_imm")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; vqshl(u)
-
-(define_insn "aarch64_<sur>qshl<u>_n<mode>"
- [(set (match_operand:VSDQ_I 0 "register_operand" "=w")
- (unspec:VSDQ_I [(match_operand:VSDQ_I 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
- VQSHL_N))]
- "TARGET_SIMD"
- "*
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[2], 0, bit_width);
- return \"<sur>qshl<u>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %2\";"
- [(set_attr "simd_type" "simd_sat_shift_imm")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-
-;; vq(r)shr(u)n_n
-
-(define_insn "aarch64_<sur>q<r>shr<u>n_n<mode>"
- [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
- (unspec:<VNARROWQ> [(match_operand:VSQN_HSDI 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
- VQSHRN_N))]
- "TARGET_SIMD"
- "*
- int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
- aarch64_simd_const_bounds (operands[2], 1, bit_width + 1);
- return \"<sur>q<r>shr<u>n\\t%<vn2>0<Vmntype>, %<v>1<Vmtype>, %2\";"
- [(set_attr "simd_type" "simd_sat_shiftn_imm")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-
-;; cm(eq|ge|le|lt|gt)
-
-(define_insn "aarch64_cm<cmp><mode>"
- [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w,w")
- (unspec:<V_cmp_result>
- [(match_operand:VSDQ_I_DI 1 "register_operand" "w,w")
- (match_operand:VSDQ_I_DI 2 "aarch64_simd_reg_or_zero" "w,Z")]
- VCMP_S))]
- "TARGET_SIMD"
- "@
- cm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>
- cm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, #0"
- [(set_attr "simd_type" "simd_cmp")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; cm(hs|hi|tst)
-
-(define_insn "aarch64_cm<cmp><mode>"
- [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w")
- (unspec:<V_cmp_result>
- [(match_operand:VSDQ_I_DI 1 "register_operand" "w")
- (match_operand:VSDQ_I_DI 2 "register_operand" "w")]
- VCMP_U))]
- "TARGET_SIMD"
- "cm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_cmp")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; fcm(eq|ge|le|lt|gt)
-
-(define_insn "aarch64_cm<cmp><mode>"
- [(set (match_operand:<V_cmp_result> 0 "register_operand" "=w,w")
- (unspec:<V_cmp_result>
- [(match_operand:VDQF 1 "register_operand" "w,w")
- (match_operand:VDQF 2 "aarch64_simd_reg_or_zero" "w,Dz")]
- VCMP_S))]
- "TARGET_SIMD"
- "@
- fcm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>
- fcm<cmp>\t%<v>0<Vmtype>, %<v>1<Vmtype>, 0"
- [(set_attr "simd_type" "simd_fcmp")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; addp
-
-(define_insn "aarch64_addp<mode>"
- [(set (match_operand:VD_BHSI 0 "register_operand" "=w")
- (unspec:VD_BHSI
- [(match_operand:VD_BHSI 1 "register_operand" "w")
- (match_operand:VD_BHSI 2 "register_operand" "w")]
- UNSPEC_ADDP))]
- "TARGET_SIMD"
- "addp\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "simd_type" "simd_add")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_addpdi"
- [(set (match_operand:DI 0 "register_operand" "=w")
- (unspec:DI
- [(match_operand:V2DI 1 "register_operand" "w")]
- UNSPEC_ADDP))]
- "TARGET_SIMD"
- "addp\t%d0, %1.2d"
- [(set_attr "simd_type" "simd_add")
- (set_attr "simd_mode" "DI")]
-)
-
-;; v(max|min)
-
-(define_expand "aarch64_<maxmin><mode>"
- [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
- (MAXMIN:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "w")
- (match_operand:VDQ_BHSI 2 "register_operand" "w")))]
- "TARGET_SIMD"
-{
- emit_insn (gen_<maxmin><mode>3 (operands[0], operands[1], operands[2]));
- DONE;
-})
-
-
-(define_insn "aarch64_<fmaxmin><mode>"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")
- (match_operand:VDQF 2 "register_operand" "w")]
- FMAXMIN))]
- "TARGET_SIMD"
- "<fmaxmin>\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fminmax")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; sqrt
-
-(define_insn "sqrt<mode>2"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (sqrt:VDQF (match_operand:VDQF 1 "register_operand" "w")))]
- "TARGET_SIMD"
- "fsqrt\\t%0.<Vtype>, %1.<Vtype>"
- [(set_attr "simd_type" "simd_fsqrt")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_expand "aarch64_sqrt<mode>"
- [(match_operand:VDQF 0 "register_operand" "=w")
- (match_operand:VDQF 1 "register_operand" "w")]
- "TARGET_SIMD"
-{
- emit_insn (gen_sqrt<mode>2 (operands[0], operands[1]));
- DONE;
-})
-
-
-;; Patterns for vector struct loads and stores.
-
-(define_insn "vec_load_lanesoi<mode>"
- [(set (match_operand:OI 0 "register_operand" "=w")
- (unspec:OI [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")
- (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- UNSPEC_LD2))]
- "TARGET_SIMD"
- "ld2\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load2")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "vec_store_lanesoi<mode>"
- [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
- (unspec:OI [(match_operand:OI 1 "register_operand" "w")
- (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- UNSPEC_ST2))]
- "TARGET_SIMD"
- "st2\\t{%S1.<Vtype> - %T1.<Vtype>}, %0"
- [(set_attr "simd_type" "simd_store2")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "vec_load_lanesci<mode>"
- [(set (match_operand:CI 0 "register_operand" "=w")
- (unspec:CI [(match_operand:CI 1 "aarch64_simd_struct_operand" "Utv")
- (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- UNSPEC_LD3))]
- "TARGET_SIMD"
- "ld3\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load3")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "vec_store_lanesci<mode>"
- [(set (match_operand:CI 0 "aarch64_simd_struct_operand" "=Utv")
- (unspec:CI [(match_operand:CI 1 "register_operand" "w")
- (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- UNSPEC_ST3))]
- "TARGET_SIMD"
- "st3\\t{%S1.<Vtype> - %U1.<Vtype>}, %0"
- [(set_attr "simd_type" "simd_store3")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "vec_load_lanesxi<mode>"
- [(set (match_operand:XI 0 "register_operand" "=w")
- (unspec:XI [(match_operand:XI 1 "aarch64_simd_struct_operand" "Utv")
- (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- UNSPEC_LD4))]
- "TARGET_SIMD"
- "ld4\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load4")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "vec_store_lanesxi<mode>"
- [(set (match_operand:XI 0 "aarch64_simd_struct_operand" "=Utv")
- (unspec:XI [(match_operand:XI 1 "register_operand" "w")
- (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- UNSPEC_ST4))]
- "TARGET_SIMD"
- "st4\\t{%S1.<Vtype> - %V1.<Vtype>}, %0"
- [(set_attr "simd_type" "simd_store4")
- (set_attr "simd_mode" "<MODE>")])
-
-;; Reload patterns for AdvSIMD register list operands.
-
-(define_expand "mov<mode>"
- [(set (match_operand:VSTRUCT 0 "aarch64_simd_nonimmediate_operand" "")
- (match_operand:VSTRUCT 1 "aarch64_simd_general_operand" ""))]
- "TARGET_SIMD"
-{
- if (can_create_pseudo_p ())
- {
- if (GET_CODE (operands[0]) != REG)
- operands[1] = force_reg (<MODE>mode, operands[1]);
- }
-})
-
-(define_insn "*aarch64_mov<mode>"
- [(set (match_operand:VSTRUCT 0 "aarch64_simd_nonimmediate_operand" "=w,Utv,w")
- (match_operand:VSTRUCT 1 "aarch64_simd_general_operand" " w,w,Utv"))]
- "TARGET_SIMD
- && (register_operand (operands[0], <MODE>mode)
- || register_operand (operands[1], <MODE>mode))"
-
-{
- switch (which_alternative)
- {
- case 0: return "#";
- case 1: return "st1\\t{%S1.16b - %<Vendreg>1.16b}, %0";
- case 2: return "ld1\\t{%S0.16b - %<Vendreg>0.16b}, %1";
- default: gcc_unreachable ();
- }
-}
- [(set_attr "simd_type" "simd_move,simd_store<nregs>,simd_load<nregs>")
- (set (attr "length") (symbol_ref "aarch64_simd_attr_length_move (insn)"))
- (set_attr "simd_mode" "<MODE>")])
-
-(define_split
- [(set (match_operand:OI 0 "register_operand" "")
- (match_operand:OI 1 "register_operand" ""))]
- "TARGET_SIMD && reload_completed"
- [(set (match_dup 0) (match_dup 1))
- (set (match_dup 2) (match_dup 3))]
-{
- int rdest = REGNO (operands[0]);
- int rsrc = REGNO (operands[1]);
- rtx dest[2], src[2];
-
- dest[0] = gen_rtx_REG (TFmode, rdest);
- src[0] = gen_rtx_REG (TFmode, rsrc);
- dest[1] = gen_rtx_REG (TFmode, rdest + 1);
- src[1] = gen_rtx_REG (TFmode, rsrc + 1);
-
- aarch64_simd_disambiguate_copy (operands, dest, src, 2);
-})
-
-(define_split
- [(set (match_operand:CI 0 "register_operand" "")
- (match_operand:CI 1 "register_operand" ""))]
- "TARGET_SIMD && reload_completed"
- [(set (match_dup 0) (match_dup 1))
- (set (match_dup 2) (match_dup 3))
- (set (match_dup 4) (match_dup 5))]
-{
- int rdest = REGNO (operands[0]);
- int rsrc = REGNO (operands[1]);
- rtx dest[3], src[3];
-
- dest[0] = gen_rtx_REG (TFmode, rdest);
- src[0] = gen_rtx_REG (TFmode, rsrc);
- dest[1] = gen_rtx_REG (TFmode, rdest + 1);
- src[1] = gen_rtx_REG (TFmode, rsrc + 1);
- dest[2] = gen_rtx_REG (TFmode, rdest + 2);
- src[2] = gen_rtx_REG (TFmode, rsrc + 2);
-
- aarch64_simd_disambiguate_copy (operands, dest, src, 3);
-})
-
-(define_split
- [(set (match_operand:XI 0 "register_operand" "")
- (match_operand:XI 1 "register_operand" ""))]
- "TARGET_SIMD && reload_completed"
- [(set (match_dup 0) (match_dup 1))
- (set (match_dup 2) (match_dup 3))
- (set (match_dup 4) (match_dup 5))
- (set (match_dup 6) (match_dup 7))]
-{
- int rdest = REGNO (operands[0]);
- int rsrc = REGNO (operands[1]);
- rtx dest[4], src[4];
-
- dest[0] = gen_rtx_REG (TFmode, rdest);
- src[0] = gen_rtx_REG (TFmode, rsrc);
- dest[1] = gen_rtx_REG (TFmode, rdest + 1);
- src[1] = gen_rtx_REG (TFmode, rsrc + 1);
- dest[2] = gen_rtx_REG (TFmode, rdest + 2);
- src[2] = gen_rtx_REG (TFmode, rsrc + 2);
- dest[3] = gen_rtx_REG (TFmode, rdest + 3);
- src[3] = gen_rtx_REG (TFmode, rsrc + 3);
-
- aarch64_simd_disambiguate_copy (operands, dest, src, 4);
-})
-
-(define_insn "aarch64_ld2<mode>_dreg"
- [(set (match_operand:OI 0 "register_operand" "=w")
- (subreg:OI
- (vec_concat:<VRL2>
- (vec_concat:<VDBL>
- (unspec:VD [(match_operand:TI 1 "aarch64_simd_struct_operand" "Utv")]
- UNSPEC_LD2)
- (vec_duplicate:VD (const_int 0)))
- (vec_concat:<VDBL>
- (unspec:VD [(match_dup 1)]
- UNSPEC_LD2)
- (vec_duplicate:VD (const_int 0)))) 0))]
- "TARGET_SIMD"
- "ld2\\t{%S0.<Vtype> - %T0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load2")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "aarch64_ld2<mode>_dreg"
- [(set (match_operand:OI 0 "register_operand" "=w")
- (subreg:OI
- (vec_concat:<VRL2>
- (vec_concat:<VDBL>
- (unspec:DX [(match_operand:TI 1 "aarch64_simd_struct_operand" "Utv")]
- UNSPEC_LD2)
- (const_int 0))
- (vec_concat:<VDBL>
- (unspec:DX [(match_dup 1)]
- UNSPEC_LD2)
- (const_int 0))) 0))]
- "TARGET_SIMD"
- "ld1\\t{%S0.1d - %T0.1d}, %1"
- [(set_attr "simd_type" "simd_load2")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "aarch64_ld3<mode>_dreg"
- [(set (match_operand:CI 0 "register_operand" "=w")
- (subreg:CI
- (vec_concat:<VRL3>
- (vec_concat:<VRL2>
- (vec_concat:<VDBL>
- (unspec:VD [(match_operand:EI 1 "aarch64_simd_struct_operand" "Utv")]
- UNSPEC_LD3)
- (vec_duplicate:VD (const_int 0)))
- (vec_concat:<VDBL>
- (unspec:VD [(match_dup 1)]
- UNSPEC_LD3)
- (vec_duplicate:VD (const_int 0))))
- (vec_concat:<VDBL>
- (unspec:VD [(match_dup 1)]
- UNSPEC_LD3)
- (vec_duplicate:VD (const_int 0)))) 0))]
- "TARGET_SIMD"
- "ld3\\t{%S0.<Vtype> - %U0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load3")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "aarch64_ld3<mode>_dreg"
- [(set (match_operand:CI 0 "register_operand" "=w")
- (subreg:CI
- (vec_concat:<VRL3>
- (vec_concat:<VRL2>
- (vec_concat:<VDBL>
- (unspec:DX [(match_operand:EI 1 "aarch64_simd_struct_operand" "Utv")]
- UNSPEC_LD3)
- (const_int 0))
- (vec_concat:<VDBL>
- (unspec:DX [(match_dup 1)]
- UNSPEC_LD3)
- (const_int 0)))
- (vec_concat:<VDBL>
- (unspec:DX [(match_dup 1)]
- UNSPEC_LD3)
- (const_int 0))) 0))]
- "TARGET_SIMD"
- "ld1\\t{%S0.1d - %U0.1d}, %1"
- [(set_attr "simd_type" "simd_load3")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "aarch64_ld4<mode>_dreg"
- [(set (match_operand:XI 0 "register_operand" "=w")
- (subreg:XI
- (vec_concat:<VRL4>
- (vec_concat:<VRL2>
- (vec_concat:<VDBL>
- (unspec:VD [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")]
- UNSPEC_LD4)
- (vec_duplicate:VD (const_int 0)))
- (vec_concat:<VDBL>
- (unspec:VD [(match_dup 1)]
- UNSPEC_LD4)
- (vec_duplicate:VD (const_int 0))))
- (vec_concat:<VRL2>
- (vec_concat:<VDBL>
- (unspec:VD [(match_dup 1)]
- UNSPEC_LD4)
- (vec_duplicate:VD (const_int 0)))
- (vec_concat:<VDBL>
- (unspec:VD [(match_dup 1)]
- UNSPEC_LD4)
- (vec_duplicate:VD (const_int 0))))) 0))]
- "TARGET_SIMD"
- "ld4\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load4")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "aarch64_ld4<mode>_dreg"
- [(set (match_operand:XI 0 "register_operand" "=w")
- (subreg:XI
- (vec_concat:<VRL4>
- (vec_concat:<VRL2>
- (vec_concat:<VDBL>
- (unspec:DX [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")]
- UNSPEC_LD4)
- (const_int 0))
- (vec_concat:<VDBL>
- (unspec:DX [(match_dup 1)]
- UNSPEC_LD4)
- (const_int 0)))
- (vec_concat:<VRL2>
- (vec_concat:<VDBL>
- (unspec:DX [(match_dup 1)]
- UNSPEC_LD4)
- (const_int 0))
- (vec_concat:<VDBL>
- (unspec:DX [(match_dup 1)]
- UNSPEC_LD4)
- (const_int 0)))) 0))]
- "TARGET_SIMD"
- "ld1\\t{%S0.1d - %V0.1d}, %1"
- [(set_attr "simd_type" "simd_load4")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_expand "aarch64_ld<VSTRUCT:nregs><VDC:mode>"
- [(match_operand:VSTRUCT 0 "register_operand" "=w")
- (match_operand:DI 1 "register_operand" "r")
- (unspec:VDC [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- "TARGET_SIMD"
-{
- enum machine_mode mode = <VSTRUCT:VSTRUCT_DREG>mode;
- rtx mem = gen_rtx_MEM (mode, operands[1]);
-
- emit_insn (gen_aarch64_ld<VSTRUCT:nregs><VDC:mode>_dreg (operands[0], mem));
- DONE;
-})
-
-(define_expand "aarch64_ld<VSTRUCT:nregs><VQ:mode>"
- [(match_operand:VSTRUCT 0 "register_operand" "=w")
- (match_operand:DI 1 "register_operand" "r")
- (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- "TARGET_SIMD"
-{
- enum machine_mode mode = <VSTRUCT:MODE>mode;
- rtx mem = gen_rtx_MEM (mode, operands[1]);
-
- emit_insn (gen_vec_load_lanes<VSTRUCT:mode><VQ:mode> (operands[0], mem));
- DONE;
-})
-
-;; Expanders for builtins to extract vector registers from large
-;; opaque integer modes.
-
-;; D-register list.
-
-(define_expand "aarch64_get_dreg<VSTRUCT:mode><VDC:mode>"
- [(match_operand:VDC 0 "register_operand" "=w")
- (match_operand:VSTRUCT 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- int part = INTVAL (operands[2]);
- rtx temp = gen_reg_rtx (<VDC:VDBL>mode);
- int offset = part * 16;
-
- emit_move_insn (temp, gen_rtx_SUBREG (<VDC:VDBL>mode, operands[1], offset));
- emit_move_insn (operands[0], gen_lowpart (<VDC:MODE>mode, temp));
- DONE;
-})
-
-;; Q-register list.
-
-(define_expand "aarch64_get_qreg<VSTRUCT:mode><VQ:mode>"
- [(match_operand:VQ 0 "register_operand" "=w")
- (match_operand:VSTRUCT 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- int part = INTVAL (operands[2]);
- int offset = part * 16;
-
- emit_move_insn (operands[0],
- gen_rtx_SUBREG (<VQ:MODE>mode, operands[1], offset));
- DONE;
-})
-
-;; Permuted-store expanders for neon intrinsics.
-
-;; Permute instructions
-
-;; vec_perm support
-
-(define_expand "vec_perm_const<mode>"
- [(match_operand:VALL 0 "register_operand")
- (match_operand:VALL 1 "register_operand")
- (match_operand:VALL 2 "register_operand")
- (match_operand:<V_cmp_result> 3)]
- "TARGET_SIMD"
-{
- if (aarch64_expand_vec_perm_const (operands[0], operands[1],
- operands[2], operands[3]))
- DONE;
- else
- FAIL;
-})
-
-(define_expand "vec_perm<mode>"
- [(match_operand:VB 0 "register_operand")
- (match_operand:VB 1 "register_operand")
- (match_operand:VB 2 "register_operand")
- (match_operand:VB 3 "register_operand")]
- "TARGET_SIMD"
-{
- aarch64_expand_vec_perm (operands[0], operands[1],
- operands[2], operands[3]);
- DONE;
-})
-
-(define_insn "aarch64_tbl1<mode>"
- [(set (match_operand:VB 0 "register_operand" "=w")
- (unspec:VB [(match_operand:V16QI 1 "register_operand" "w")
- (match_operand:VB 2 "register_operand" "w")]
- UNSPEC_TBL))]
- "TARGET_SIMD"
- "tbl\\t%0.<Vtype>, {%1.16b}, %2.<Vtype>"
- [(set_attr "simd_type" "simd_tbl")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; Two source registers.
-
-(define_insn "aarch64_tbl2v16qi"
- [(set (match_operand:V16QI 0 "register_operand" "=w")
- (unspec:V16QI [(match_operand:OI 1 "register_operand" "w")
- (match_operand:V16QI 2 "register_operand" "w")]
- UNSPEC_TBL))]
- "TARGET_SIMD"
- "tbl\\t%0.16b, {%S1.16b - %T1.16b}, %2.16b"
- [(set_attr "simd_type" "simd_tbl")
- (set_attr "simd_mode" "V16QI")]
-)
-
-(define_insn_and_split "aarch64_combinev16qi"
- [(set (match_operand:OI 0 "register_operand" "=w")
- (unspec:OI [(match_operand:V16QI 1 "register_operand" "w")
- (match_operand:V16QI 2 "register_operand" "w")]
- UNSPEC_CONCAT))]
- "TARGET_SIMD"
- "#"
- "&& reload_completed"
- [(const_int 0)]
-{
- aarch64_split_combinev16qi (operands);
- DONE;
-})
-
-(define_insn "aarch64_<PERMUTE:perm_insn><PERMUTE:perm_hilo><mode>"
- [(set (match_operand:VALL 0 "register_operand" "=w")
- (unspec:VALL [(match_operand:VALL 1 "register_operand" "w")
- (match_operand:VALL 2 "register_operand" "w")]
- PERMUTE))]
- "TARGET_SIMD"
- "<PERMUTE:perm_insn><PERMUTE:perm_hilo>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_<PERMUTE:perm_insn>")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-(define_insn "aarch64_st2<mode>_dreg"
- [(set (match_operand:TI 0 "aarch64_simd_struct_operand" "=Utv")
- (unspec:TI [(match_operand:OI 1 "register_operand" "w")
- (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- UNSPEC_ST2))]
- "TARGET_SIMD"
- "st2\\t{%S1.<Vtype> - %T1.<Vtype>}, %0"
- [(set_attr "simd_type" "simd_store2")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "aarch64_st2<mode>_dreg"
- [(set (match_operand:TI 0 "aarch64_simd_struct_operand" "=Utv")
- (unspec:TI [(match_operand:OI 1 "register_operand" "w")
- (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- UNSPEC_ST2))]
- "TARGET_SIMD"
- "st1\\t{%S1.1d - %T1.1d}, %0"
- [(set_attr "simd_type" "simd_store2")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "aarch64_st3<mode>_dreg"
- [(set (match_operand:EI 0 "aarch64_simd_struct_operand" "=Utv")
- (unspec:EI [(match_operand:CI 1 "register_operand" "w")
- (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- UNSPEC_ST3))]
- "TARGET_SIMD"
- "st3\\t{%S1.<Vtype> - %U1.<Vtype>}, %0"
- [(set_attr "simd_type" "simd_store3")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "aarch64_st3<mode>_dreg"
- [(set (match_operand:EI 0 "aarch64_simd_struct_operand" "=Utv")
- (unspec:EI [(match_operand:CI 1 "register_operand" "w")
- (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- UNSPEC_ST3))]
- "TARGET_SIMD"
- "st1\\t{%S1.1d - %U1.1d}, %0"
- [(set_attr "simd_type" "simd_store3")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "aarch64_st4<mode>_dreg"
- [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
- (unspec:OI [(match_operand:XI 1 "register_operand" "w")
- (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- UNSPEC_ST4))]
- "TARGET_SIMD"
- "st4\\t{%S1.<Vtype> - %V1.<Vtype>}, %0"
- [(set_attr "simd_type" "simd_store4")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_insn "aarch64_st4<mode>_dreg"
- [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
- (unspec:OI [(match_operand:XI 1 "register_operand" "w")
- (unspec:DX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- UNSPEC_ST4))]
- "TARGET_SIMD"
- "st1\\t{%S1.1d - %V1.1d}, %0"
- [(set_attr "simd_type" "simd_store4")
- (set_attr "simd_mode" "<MODE>")])
-
-(define_expand "aarch64_st<VSTRUCT:nregs><VDC:mode>"
- [(match_operand:DI 0 "register_operand" "r")
- (match_operand:VSTRUCT 1 "register_operand" "w")
- (unspec:VDC [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- "TARGET_SIMD"
-{
- enum machine_mode mode = <VSTRUCT:VSTRUCT_DREG>mode;
- rtx mem = gen_rtx_MEM (mode, operands[0]);
-
- emit_insn (gen_aarch64_st<VSTRUCT:nregs><VDC:mode>_dreg (mem, operands[1]));
- DONE;
-})
-
-(define_expand "aarch64_st<VSTRUCT:nregs><VQ:mode>"
- [(match_operand:DI 0 "register_operand" "r")
- (match_operand:VSTRUCT 1 "register_operand" "w")
- (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
- "TARGET_SIMD"
-{
- enum machine_mode mode = <VSTRUCT:MODE>mode;
- rtx mem = gen_rtx_MEM (mode, operands[0]);
-
- emit_insn (gen_vec_store_lanes<VSTRUCT:mode><VQ:mode> (mem, operands[1]));
- DONE;
-})
-
-;; Expander for builtins to insert vector registers into large
-;; opaque integer modes.
-
-;; Q-register list. We don't need a D-reg inserter as we zero
-;; extend them in arm_neon.h and insert the resulting Q-regs.
-
-(define_expand "aarch64_set_qreg<VSTRUCT:mode><VQ:mode>"
- [(match_operand:VSTRUCT 0 "register_operand" "+w")
- (match_operand:VSTRUCT 1 "register_operand" "0")
- (match_operand:VQ 2 "register_operand" "w")
- (match_operand:SI 3 "immediate_operand" "i")]
- "TARGET_SIMD"
-{
- int part = INTVAL (operands[3]);
- int offset = part * 16;
-
- emit_move_insn (operands[0], operands[1]);
- emit_move_insn (gen_rtx_SUBREG (<VQ:MODE>mode, operands[0], offset),
- operands[2]);
- DONE;
-})
-
-;; Standard pattern name vec_init<mode>.
-
-(define_expand "vec_init<mode>"
- [(match_operand:VALL 0 "register_operand" "")
- (match_operand 1 "" "")]
- "TARGET_SIMD"
-{
- aarch64_expand_vector_init (operands[0], operands[1]);
- DONE;
-})
-
-(define_insn "*aarch64_simd_ld1r<mode>"
- [(set (match_operand:VALLDI 0 "register_operand" "=w")
- (vec_duplicate:VALLDI
- (match_operand:<VEL> 1 "aarch64_simd_struct_operand" "Utv")))]
- "TARGET_SIMD"
- "ld1r\\t{%0.<Vtype>}, %1"
- [(set_attr "simd_type" "simd_load1r")
- (set_attr "simd_mode" "<MODE>")])