#define CF4(N, X) CODE_FOR_##N##X##4
#define CF10(N, X) CODE_FOR_##N##X
-#define VAR1(T, N, MAP, FLAG, A) \
- {#N #A, UP (A), CF##MAP (N, A), 0, TYPES_##T, FLAG_##FLAG},
+/* Define cascading VAR<N> macros that are used from
+ aarch64-builtin-iterators.h to iterate over modes. These definitions
+ will end up generating a number of VAR1 expansions and code later on in the
+ file should redefine VAR1 to whatever it needs to process on a per-mode
+ basis. */
#define VAR2(T, N, MAP, FLAG, A, B) \
VAR1 (T, N, MAP, FLAG, A) \
VAR1 (T, N, MAP, FLAG, B)
#include "aarch64-builtin-iterators.h"
+/* The builtins below should be expanded through the standard optabs
+ CODE_FOR_[u]avg<mode>3_[floor,ceil]. However the mapping scheme in
+ aarch64-simd-builtins.def does not easily allow us to have a pre-mode
+ ("uavg") and post-mode string ("_ceil") in the CODE_FOR_* construction.
+ So the builtins use a name that is natural for AArch64 instructions
+ e.g. "aarch64_srhadd<mode>" and we re-map these to the optab-related
+ CODE_FOR_ here. */
+#undef VAR1
+#define VAR1(F,T1,T2,I,M) \
+constexpr insn_code CODE_FOR_aarch64_##F##M = CODE_FOR_##T1##M##3##T2;
+
+BUILTIN_VDQ_BHSI (srhadd, avg, _ceil, 0)
+BUILTIN_VDQ_BHSI (urhadd, uavg, _ceil, 0)
+BUILTIN_VDQ_BHSI (shadd, avg, _floor, 0)
+BUILTIN_VDQ_BHSI (uhadd, uavg, _floor, 0)
+
+#undef VAR1
+#define VAR1(T, N, MAP, FLAG, A) \
+ {#N #A, UP (A), CF##MAP (N, A), 0, TYPES_##T, FLAG_##FLAG},
+
static aarch64_simd_builtin_datum aarch64_simd_builtin_data[] = {
#include "aarch64-simd-builtins.def"
};
;; <su><r>h<addsub>.
-(define_expand "<u>avg<mode>3_floor"
+(define_expand "<su_optab>avg<mode>3_floor"
[(set (match_operand:VDQ_BHSI 0 "register_operand")
- (unspec:VDQ_BHSI [(match_operand:VDQ_BHSI 1 "register_operand")
- (match_operand:VDQ_BHSI 2 "register_operand")]
- HADD))]
+ (truncate:VDQ_BHSI
+ (ashiftrt:<V2XWIDE>
+ (plus:<V2XWIDE>
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQ_BHSI 1 "register_operand"))
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQ_BHSI 2 "register_operand")))
+ (match_dup 3))))]
"TARGET_SIMD"
+ {
+ operands[3] = CONST1_RTX (<V2XWIDE>mode);
+ }
)
-(define_expand "<u>avg<mode>3_ceil"
+(define_expand "<su_optab>avg<mode>3_ceil"
[(set (match_operand:VDQ_BHSI 0 "register_operand")
- (unspec:VDQ_BHSI [(match_operand:VDQ_BHSI 1 "register_operand")
- (match_operand:VDQ_BHSI 2 "register_operand")]
- RHADD))]
+ (truncate:VDQ_BHSI
+ (ashiftrt:<V2XWIDE>
+ (plus:<V2XWIDE>
+ (plus:<V2XWIDE>
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQ_BHSI 1 "register_operand"))
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQ_BHSI 2 "register_operand")))
+ (match_dup 3))
+ (match_dup 3))))]
"TARGET_SIMD"
+ {
+ operands[3] = CONST1_RTX (<V2XWIDE>mode);
+ }
)
-(define_insn "aarch64_<sur>h<addsub><mode><vczle><vczbe>"
+(define_expand "aarch64_<su>hsub<mode>"
+ [(set (match_operand:VDQ_BHSI 0 "register_operand")
+ (truncate:VDQ_BHSI
+ (ashiftrt:<V2XWIDE>
+ (minus:<V2XWIDE>
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQ_BHSI 1 "register_operand"))
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQ_BHSI 2 "register_operand")))
+ (match_dup 3))))]
+ "TARGET_SIMD"
+ {
+ operands[3] = CONST1_RTX (<V2XWIDE>mode);
+ }
+)
+
+(define_insn "*aarch64_<su>h<ADDSUB:optab><mode><vczle><vczbe>_insn"
[(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
- (unspec:VDQ_BHSI [(match_operand:VDQ_BHSI 1 "register_operand" "w")
- (match_operand:VDQ_BHSI 2 "register_operand" "w")]
- HADDSUB))]
+ (truncate:VDQ_BHSI
+ (ashiftrt:<V2XWIDE>
+ (ADDSUB:<V2XWIDE>
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQ_BHSI 1 "register_operand" "w"))
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQ_BHSI 2 "register_operand" "w")))
+ (match_operand:<V2XWIDE> 3 "aarch64_simd_imm_one"))))]
"TARGET_SIMD"
- "<sur>h<addsub>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "type" "neon_<addsub>_halve<q>")]
+ "<su>h<ADDSUB:optab>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
+ [(set_attr "type" "neon_<ADDSUB:optab>_halve<q>")]
+)
+
+(define_insn "*aarch64_<su>rhadd<mode><vczle><vczbe>_insn"
+ [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
+ (truncate:VDQ_BHSI
+ (ashiftrt:<V2XWIDE>
+ (plus:<V2XWIDE>
+ (plus:<V2XWIDE>
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQ_BHSI 1 "register_operand" "w"))
+ (ANY_EXTEND:<V2XWIDE>
+ (match_operand:VDQ_BHSI 2 "register_operand" "w")))
+ (match_operand:<V2XWIDE> 3 "aarch64_simd_imm_one"))
+ (match_dup 3))))]
+ "TARGET_SIMD"
+ "<su>rhadd\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
+ [(set_attr "type" "neon_add_halve<q>")]
)
;; <r><addsub>hn<q>.