}
)
-(define_insn "aarch64_<sur>adalp<mode>"
+(define_expand "aarch64_<su>adalp<mode>"
+ [(set (match_operand:<VDBLW> 0 "register_operand")
+ (plus:<VDBLW>
+ (plus:<VDBLW>
+ (vec_select:<VDBLW>
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQV_L 2 "register_operand"))
+ (match_dup 3))
+ (vec_select:<VDBLW> (ANY_EXTEND:<V2XWIDE> (match_dup 2))
+ (match_dup 4)))
+ (match_operand:<VDBLW> 1 "register_operand")))]
+ "TARGET_SIMD"
+ {
+ int nunits = GET_MODE_NUNITS (<MODE>mode).to_constant () / 2;
+ operands[3] = aarch64_gen_stepped_int_parallel (nunits, 0, 2);
+ operands[4] = aarch64_gen_stepped_int_parallel (nunits, 1, 2);
+ }
+)
+
+(define_insn "*aarch64_<su>adalp<mode><vczle><vczbe>_insn"
[(set (match_operand:<VDBLW> 0 "register_operand" "=w")
- (unspec:<VDBLW> [(match_operand:VDQV_L 2 "register_operand" "w")
- (match_operand:<VDBLW> 1 "register_operand" "0")]
- ADALP))]
- "TARGET_SIMD"
- "<sur>adalp\t%0.<Vwhalf>, %2.<Vtype>"
+ (plus:<VDBLW>
+ (plus:<VDBLW>
+ (vec_select:<VDBLW>
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQV_L 2 "register_operand" "w"))
+ (match_operand:<V2XWIDE> 3 "vect_par_cnst_even_or_odd_half" ""))
+ (vec_select:<VDBLW> (ANY_EXTEND:<V2XWIDE> (match_dup 2))
+ (match_operand:<V2XWIDE> 4 "vect_par_cnst_even_or_odd_half" "")))
+ (match_operand:<VDBLW> 1 "register_operand" "0")))]
+ "TARGET_SIMD
+ && !rtx_equal_p (operands[3], operands[4])"
+ "<su>adalp\t%0.<Vwhalf>, %2.<Vtype>"
[(set_attr "type" "neon_reduc_add<q>")]
)
[(set_attr "type" "neon_reduc_add<VDQV_L:q>")]
)
-(define_insn "aarch64_<su>addlp<mode>"
- [(set (match_operand:<VDBLW> 0 "register_operand" "=w")
- (unspec:<VDBLW> [(match_operand:VDQV_L 1 "register_operand" "w")]
- USADDLP))]
+(define_expand "aarch64_<su>addlp<mode>"
+ [(set (match_operand:<VDBLW> 0 "register_operand")
+ (plus:<VDBLW>
+ (vec_select:<VDBLW>
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQV_L 1 "register_operand"))
+ (match_dup 2))
+ (vec_select:<VDBLW> (ANY_EXTEND:<V2XWIDE> (match_dup 1))
+ (match_dup 3))))]
"TARGET_SIMD"
+ {
+ int nunits = GET_MODE_NUNITS (<MODE>mode).to_constant () / 2;
+ operands[2] = aarch64_gen_stepped_int_parallel (nunits, 0, 2);
+ operands[3] = aarch64_gen_stepped_int_parallel (nunits, 1, 2);
+ }
+)
+
+(define_insn "*aarch64_<su>addlp<mode><vczle><vczbe>_insn"
+ [(set (match_operand:<VDBLW> 0 "register_operand" "=w")
+ (plus:<VDBLW>
+ (vec_select:<VDBLW>
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQV_L 1 "register_operand" "w"))
+ (match_operand:<V2XWIDE> 2 "vect_par_cnst_even_or_odd_half"))
+ (vec_select:<VDBLW> (ANY_EXTEND:<V2XWIDE> (match_dup 1))
+ (match_operand:<V2XWIDE> 3 "vect_par_cnst_even_or_odd_half"))))]
+ "TARGET_SIMD
+ && !rtx_equal_p (operands[2], operands[3])"
"<su>addlp\\t%0.<Vwhalf>, %1.<Vtype>"
[(set_attr "type" "neon_reduc_add<q>")]
)
UNSPEC_SSHLL ; Used in aarch64-simd.md.
UNSPEC_USHLL ; Used in aarch64-simd.md.
UNSPEC_ADDP ; Used in aarch64-simd.md.
- UNSPEC_SADDLP ; Used in aarch64-simd.md.
- UNSPEC_UADDLP ; Used in aarch64-simd.md.
UNSPEC_TBL ; Used in vector permute patterns.
UNSPEC_TBX ; Used in vector permute patterns.
UNSPEC_CONCAT ; Used in vector permute patterns.
;; Int Iterators.
;; -------------------------------------------------------------------
-;; The unspec codes for the SADALP, UADALP AdvancedSIMD instructions.
-(define_int_iterator ADALP [UNSPEC_SADALP UNSPEC_UADALP])
-
(define_int_iterator MAXMINV [UNSPEC_UMAXV UNSPEC_UMINV
UNSPEC_SMAXV UNSPEC_SMINV])
(define_int_iterator SVE_INT_ADDV [UNSPEC_SADDV UNSPEC_UADDV])
-(define_int_iterator USADDLP [UNSPEC_SADDLP UNSPEC_UADDLP])
-
(define_int_iterator USADDLV [UNSPEC_SADDLV UNSPEC_UADDLV])
(define_int_iterator LOGICALF [UNSPEC_ANDF UNSPEC_IORF UNSPEC_XORF])
;; "s" for signed operations and "u" for unsigned ones.
(define_int_attr su [(UNSPEC_SADDV "s")
(UNSPEC_UADDV "u")
- (UNSPEC_SADDLP "s")
- (UNSPEC_UADDLP "u")
(UNSPEC_SADDLV "s")
(UNSPEC_UADDLV "u")
(UNSPEC_UNPACKSHI "s")
return aarch64_simd_check_vect_par_cnst_half (op, mode, false);
})
+;; PARALLEL for a vec_select that selects all the even or all the odd
+;; elements of a vector of MODE.
+(define_special_predicate "vect_par_cnst_even_or_odd_half"
+ (match_code "parallel")
+{
+ int nunits = XVECLEN (op, 0);
+ if (!known_eq (GET_MODE_NUNITS (mode), nunits * 2))
+ return false;
+ rtx first = XVECEXP (op, 0, 0);
+ if (!CONST_INT_P (first))
+ return false;
+ return (INTVAL (first) == 0 || INTVAL (first) == 1)
+ && aarch64_stepped_int_parallel_p (op, 2);
+})
+
(define_predicate "descending_int_parallel"
(match_code "parallel")
{