diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 104088f67d2..5130f46c0da 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -1083,6 +1083,39 @@ [(set_attr "type" "neon_ins, neon_from_gp, neon_load1_one_lane")] ) +(define_insn "aarch64_simd_set_zero" + [(set (match_operand:VALL_F16 0 "register_operand" "=w") + (unspec:VALL_F16 [(match_operand:VALL_F16 1 "register_operand" "0") + (match_operand:SI 2 "immediate_operand" "i")] + UNSPEC_SETZERO))] + "TARGET_SIMD" + { + if (GET_MODE_INNER (mode) == DImode) + return "ins\\t%0.[%p2], xzr"; + return "ins\\t%0.[%p2], wzr"; + } + [(set_attr "type" "neon_ins")] +) + +(define_insn_and_split "aarch64_simd_vec_set_zero" + [(set (match_operand:VALL_F16 0 "register_operand" "=w") + (vec_merge:VALL_F16 + (match_operand:VALL_F16 1 "const_dup0_operand" "w") + (match_operand:VALL_F16 3 "register_operand" "0") + (match_operand:SI 2 "immediate_operand" "i")))] + "TARGET_SIMD" + "#" + "&& 1" + [(const_int 0)] + { + int elt = ENDIAN_LANE_N (, exact_log2 (INTVAL (operands[2]))); + operands[2] = GEN_INT ((HOST_WIDE_INT) 1 << elt); + emit_insn (gen_aarch64_simd_set_zero (operands[0], operands[3], operands[2])); + DONE; + } + [(set_attr "type" "neon_ins")] +) + (define_insn "@aarch64_simd_vec_copy_lane" [(set (match_operand:VALL_F16 0 "register_operand" "=w") (vec_merge:VALL_F16 diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 5b26443e5b6..8064841ebb4 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -839,6 +839,7 @@ UNSPEC_FCMUL_CONJ ; Used in aarch64-simd.md. UNSPEC_FCMLA_CONJ ; Used in aarch64-simd.md. UNSPEC_FCMLA180_CONJ ; Used in aarch64-simd.md. + UNSPEC_SETZERO ; Used in aarch64-simd.md. UNSPEC_ASRD ; Used in aarch64-sve.md. UNSPEC_ADCLB ; Used in aarch64-sve2.md. UNSPEC_ADCLT ; Used in aarch64-sve2.md. diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index ff7f73d3f30..901fa1bd7f9 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -49,6 +49,13 @@ return CONST_INT_P (op) && IN_RANGE (INTVAL (op), 1, 3); }) +(define_predicate "const_dup0_operand" + (match_code "const_vector") +{ + op = unwrap_const_vec_duplicate (op); + return CONST_INT_P (op) && rtx_equal_p (op, const0_rtx); +}) + (define_predicate "subreg_lowpart_operator" (ior (match_code "truncate") (and (match_code "subreg")