UNSPEC_LCBB
; Vector
- UNSPEC_VEC_SMULT_HI
- UNSPEC_VEC_UMULT_HI
- UNSPEC_VEC_SMULT_LO
UNSPEC_VEC_SMULT_EVEN
UNSPEC_VEC_UMULT_EVEN
UNSPEC_VEC_SMULT_ODD
; vec_unpacks_float_lo
; vec_unpacku_float_hi
; vec_unpacku_float_lo
+
+(define_expand "avg<mode>3_ceil"
+ [(set (match_operand:VIT_HW_VXE3_T 0 "register_operand")
+ (unspec:VIT_HW_VXE3_T [(match_operand:VIT_HW_VXE3_T 1 "register_operand")
+ (match_operand:VIT_HW_VXE3_T 2 "register_operand")]
+ UNSPEC_VEC_AVG))]
+ "TARGET_VX")
+
+(define_expand "uavg<mode>3_ceil"
+ [(set (match_operand:VIT_HW_VXE3_T 0 "register_operand")
+ (unspec:VIT_HW_VXE3_T [(match_operand:VIT_HW_VXE3_T 1 "register_operand")
+ (match_operand:VIT_HW_VXE3_T 2 "register_operand")]
+ UNSPEC_VEC_AVGU))]
+ "TARGET_VX")
+
+(define_expand "smul<mode>3_highpart"
+ [(set (match_operand:VIT_HW_VXE3_DT 0 "register_operand")
+ (smul_highpart:VIT_HW_VXE3_DT (match_operand:VIT_HW_VXE3_DT 1 "register_operand")
+ (match_operand:VIT_HW_VXE3_DT 2 "register_operand")))]
+ "TARGET_VX")
+
+(define_expand "umul<mode>3_highpart"
+ [(set (match_operand:VIT_HW_VXE3_DT 0 "register_operand")
+ (umul_highpart:VIT_HW_VXE3_DT (match_operand:VIT_HW_VXE3_DT 1 "register_operand")
+ (match_operand:VIT_HW_VXE3_DT 2 "register_operand")))]
+ "TARGET_VX")
; vmhb, vmhh, vmhf, vmhg, vmhq
(define_insn "vec_smulh<mode>"
- [(set (match_operand:VIT_HW_VXE3_DT 0 "register_operand" "=v")
- (unspec:VIT_HW_VXE3_DT [(match_operand:VIT_HW_VXE3_DT 1 "register_operand" "v")
- (match_operand:VIT_HW_VXE3_DT 2 "register_operand" "v")]
- UNSPEC_VEC_SMULT_HI))]
+ [(set (match_operand:VIT_HW_VXE3_DT 0 "register_operand" "=v")
+ (smul_highpart:VIT_HW_VXE3_DT (match_operand:VIT_HW_VXE3_DT 1 "register_operand" "v")
+ (match_operand:VIT_HW_VXE3_DT 2 "register_operand" "v")))]
"TARGET_VX"
"vmh<bhfgq>\t%v0,%v1,%v2"
[(set_attr "op_type" "VRR")])
; vmlhb, vmlhh, vmlhf, vmlhg, vmlhq
(define_insn "vec_umulh<mode>"
- [(set (match_operand:VIT_HW_VXE3_DT 0 "register_operand" "=v")
- (unspec:VIT_HW_VXE3_DT [(match_operand:VIT_HW_VXE3_DT 1 "register_operand" "v")
- (match_operand:VIT_HW_VXE3_DT 2 "register_operand" "v")]
- UNSPEC_VEC_UMULT_HI))]
+ [(set (match_operand:VIT_HW_VXE3_DT 0 "register_operand" "=v")
+ (umul_highpart:VIT_HW_VXE3_DT (match_operand:VIT_HW_VXE3_DT 1 "register_operand" "v")
+ (match_operand:VIT_HW_VXE3_DT 2 "register_operand" "v")))]
"TARGET_VX"
"vmlh<bhfgq>\t%v0,%v1,%v2"
[(set_attr "op_type" "VRR")])
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O3 -mzarch -march=z16 -ftree-vectorize -fdump-tree-optimized" } */
+
+#define TEST(T1,T2,N) \
+ void \
+ avg##T1 (signed T1 *__restrict res, signed T1 *__restrict a, \
+ signed T1 *__restrict b) \
+ { \
+ for (int i = 0; i < N; ++i) \
+ res[i] = ((signed T2)a[i] + b[i] + 1) >> 1; \
+ } \
+ \
+ void \
+ uavg##T1 (unsigned T1 *__restrict res, unsigned T1 *__restrict a, \
+ unsigned T1 *__restrict b) \
+ { \
+ for (int i = 0; i < N; ++i) \
+ res[i] = ((unsigned T2)a[i] + b[i] + 1) >> 1; \
+ }
+
+TEST(char,short,16)
+TEST(short,int,8)
+TEST(int,long,4)
+TEST(long,__int128,2)
+
+/* { dg-final { scan-tree-dump-times "\.AVG_CEIL" 8 "optimized" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O3 -mzarch -march=arch15 -ftree-vectorize -fdump-tree-optimized" } */
+
+#define TEST(T1,T2,N,S) \
+ void \
+ mulh##T1 (signed T1 *__restrict res, \
+ signed T1 *__restrict l, \
+ signed T1 *__restrict r) \
+ { \
+ for (int i = 0; i < N; ++i) \
+ res[i] = (signed T1) (((signed T2)l[i] * (signed T2)r[i]) >> S); \
+ } \
+ \
+ void \
+ umulh##T1 (unsigned T1 *__restrict res, \
+ unsigned T1 *__restrict l, \
+ unsigned T1 *__restrict r) \
+ { \
+ for (int i = 0; i < N; ++i) \
+ res[i] = (unsigned T1) \
+ (((unsigned T2)l[i] * (unsigned T2)r[i]) >> S); \
+ }
+
+TEST(char,short,16,8)
+TEST(short,int,8,16)
+TEST(int,long,4,32)
+TEST(long,__int128,2,64)
+
+/* { dg-final { scan-tree-dump-times "\.MULH" 8 "optimized" } } */