[gcc r13-5910] RISC-V: Add vnsrl/vnsra/vncvt/vmerge/vmv C/C++ support
Kito Cheng
kito@gcc.gnu.org
Sun Feb 12 07:34:40 GMT 2023
https://gcc.gnu.org/g:6271a07219a7d764ef59607836c01e0084c3d50c
commit r13-5910-g6271a07219a7d764ef59607836c01e0084c3d50c
Author: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
Date: Fri Feb 10 05:45:44 2023 +0800
RISC-V: Add vnsrl/vnsra/vncvt/vmerge/vmv C/C++ support
gcc/ChangeLog:
* config/riscv/constraints.md (Wbr): Remove unused constraint.
* config/riscv/predicates.md: Fix move operand predicate.
* config/riscv/riscv-vector-builtins-bases.cc (class vnshift): New class.
(class vncvt_x): Ditto.
(class vmerge): Ditto.
(class vmv_v): Ditto.
(BASE): Ditto.
* config/riscv/riscv-vector-builtins-bases.h: Ditto.
* config/riscv/riscv-vector-builtins-functions.def (vsra): Ditto.
(vsrl): Ditto.
(vnsrl): Ditto.
(vnsra): Ditto.
(vncvt_x): Ditto.
(vmerge): Ditto.
(vmv_v): Ditto.
* config/riscv/riscv-vector-builtins-shapes.cc (struct narrow_alu_def): Ditto.
(struct move_def): Ditto.
(SHAPE): Ditto.
* config/riscv/riscv-vector-builtins-shapes.h: Ditto.
* config/riscv/riscv-vector-builtins.cc (DEF_RVV_WEXTI_OPS): New variable.
(DEF_RVV_WEXTU_OPS): Ditto
* config/riscv/riscv-vector-builtins.def (x_x_w): Fix type for suffix.
(v_v): Ditto.
(v_x): Ditto.
(x_w): Ditto.
(x): Ditto.
* config/riscv/riscv.cc (riscv_print_operand): Refine ASM printting rule.
* config/riscv/vector-iterators.md (nmsac):New iterator.
(nmsub): New iterator.
* config/riscv/vector.md (@pred_merge<mode>): New pattern.
(@pred_merge<mode>_scalar): New pattern.
(*pred_merge<mode>_scalar): New pattern.
(*pred_merge<mode>_extended_scalar): New pattern.
(@pred_narrow_<optab><mode>): New pattern.
(@pred_narrow_<optab><mode>_scalar): New pattern.
(@pred_trunc<mode>): New pattern.
Diff:
---
gcc/config/riscv/constraints.md | 13 --
gcc/config/riscv/predicates.md | 7 +-
gcc/config/riscv/riscv-vector-builtins-bases.cc | 78 +++++++
gcc/config/riscv/riscv-vector-builtins-bases.h | 5 +
.../riscv/riscv-vector-builtins-functions.def | 17 +-
gcc/config/riscv/riscv-vector-builtins-shapes.cc | 54 +++++
gcc/config/riscv/riscv-vector-builtins-shapes.h | 2 +
gcc/config/riscv/riscv-vector-builtins.cc | 115 ++++++++++
gcc/config/riscv/riscv-vector-builtins.def | 5 +-
gcc/config/riscv/riscv.cc | 42 +++-
gcc/config/riscv/vector-iterators.md | 3 +
gcc/config/riscv/vector.md | 251 +++++++++++++++++++--
12 files changed, 536 insertions(+), 56 deletions(-)
diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index b646ad4853c..a051d466ae2 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -166,16 +166,3 @@
"Vector duplicate memory operand"
(and (match_code "mem")
(match_code "reg" "0")))
-
-;; (vec_duplicate:V (const_int 2863311530 [0xaaaaaaaa])) of pred_broadcast
-;; is CSEed into (const_vector:V (const_int 2863311530 [0xaaaaaaaa])) here
-;; which is not the pattern matching we want since we can't generate
-;; instruction directly for it when SEW = 64 and !TARGET_64BIT. We should
-;; not allow RA (register allocation) allocate a DImode register in
-;; pred_broadcast pattern.
-(define_constraint "Wbr"
- "@internal
- Broadcast register operand"
- (and (match_code "reg")
- (match_test "REGNO (op) <= GP_REG_LAST
- && direct_broadcast_operand (op, GET_MODE (op))")))
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 8d2ccb0f7a2..fe2c5ba3c5c 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -288,10 +288,9 @@
(match_test "op == CONSTM1_RTX (GET_MODE (op))")))
(define_predicate "vector_merge_operand"
- (ior (match_operand 0 "memory_operand")
- (ior (match_operand 0 "register_operand")
- (match_test "GET_CODE (op) == UNSPEC
- && (XINT (op, 1) == UNSPEC_VUNDEF)"))))
+ (ior (match_operand 0 "register_operand")
+ (match_test "GET_CODE (op) == UNSPEC
+ && (XINT (op, 1) == UNSPEC_VUNDEF)")))
(define_predicate "vector_arith_operand"
(ior (match_operand 0 "register_operand")
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index bcf2dfe805a..30f9734c36b 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -396,6 +396,74 @@ public:
}
};
+/* Implements vnsrl/vnsra. */
+template<rtx_code CODE>
+class vnshift : public function_base
+{
+public:
+ rtx expand (function_expander &e) const override
+ {
+ switch (e.op_info->op)
+ {
+ case OP_TYPE_wx:
+ return e.use_exact_insn (
+ code_for_pred_narrow_scalar (CODE, e.vector_mode ()));
+ case OP_TYPE_wv:
+ return e.use_exact_insn (code_for_pred_narrow (CODE, e.vector_mode ()));
+ default:
+ gcc_unreachable ();
+ }
+ }
+};
+
+/* Implements vncvt. */
+class vncvt_x : public function_base
+{
+public:
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (code_for_pred_trunc (e.vector_mode ()));
+ }
+};
+
+/* Implements vmerge. */
+class vmerge : public function_base
+{
+public:
+ bool apply_mask_policy_p () const override { return false; }
+ bool use_mask_predication_p () const override { return false; }
+ rtx expand (function_expander &e) const override
+ {
+ switch (e.op_info->op)
+ {
+ case OP_TYPE_vvm:
+ return e.use_exact_insn (code_for_pred_merge (e.vector_mode ()));
+ case OP_TYPE_vxm:
+ return e.use_exact_insn (code_for_pred_merge_scalar (e.vector_mode ()));
+ default:
+ gcc_unreachable ();
+ }
+ }
+};
+
+/* Implements vmv.v.x/vmv.v.v. */
+class vmv_v : public function_base
+{
+public:
+ rtx expand (function_expander &e) const override
+ {
+ switch (e.op_info->op)
+ {
+ case OP_TYPE_v:
+ return e.use_exact_insn (code_for_pred_mov (e.vector_mode ()));
+ case OP_TYPE_x:
+ return e.use_exact_insn (code_for_pred_broadcast (e.vector_mode ()));
+ default:
+ gcc_unreachable ();
+ }
+ }
+};
+
static CONSTEXPR const vsetvl<false> vsetvl_obj;
static CONSTEXPR const vsetvl<true> vsetvlmax_obj;
static CONSTEXPR const loadstore<false, LST_UNIT_STRIDE, false> vle_obj;
@@ -458,6 +526,11 @@ static CONSTEXPR const vadc vadc_obj;
static CONSTEXPR const vsbc vsbc_obj;
static CONSTEXPR const vmadc vmadc_obj;
static CONSTEXPR const vmsbc vmsbc_obj;
+static CONSTEXPR const vnshift<LSHIFTRT> vnsrl_obj;
+static CONSTEXPR const vnshift<ASHIFTRT> vnsra_obj;
+static CONSTEXPR const vncvt_x vncvt_x_obj;
+static CONSTEXPR const vmerge vmerge_obj;
+static CONSTEXPR const vmv_v vmv_v_obj;
static CONSTEXPR const binop<SS_PLUS> vsadd_obj;
static CONSTEXPR const binop<SS_MINUS> vssub_obj;
static CONSTEXPR const binop<US_PLUS> vsaddu_obj;
@@ -530,6 +603,11 @@ BASE (vadc)
BASE (vsbc)
BASE (vmadc)
BASE (vmsbc)
+BASE (vnsrl)
+BASE (vnsra)
+BASE (vncvt_x)
+BASE (vmerge)
+BASE (vmv_v)
BASE (vsadd)
BASE (vssub)
BASE (vsaddu)
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h
index 6a8747b184e..411db5627ee 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.h
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.h
@@ -86,6 +86,11 @@ extern const function_base *const vadc;
extern const function_base *const vsbc;
extern const function_base *const vmadc;
extern const function_base *const vmsbc;
+extern const function_base *const vnsrl;
+extern const function_base *const vnsra;
+extern const function_base *const vncvt_x;
+extern const function_base *const vmerge;
+extern const function_base *const vmv_v;
extern const function_base *const vsadd;
extern const function_base *const vssub;
extern const function_base *const vsaddu;
diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def b/gcc/config/riscv/riscv-vector-builtins-functions.def
index 6d328537ab8..28483463d64 100644
--- a/gcc/config/riscv/riscv-vector-builtins-functions.def
+++ b/gcc/config/riscv/riscv-vector-builtins-functions.def
@@ -69,8 +69,8 @@ DEF_RVV_FUNCTION (vand, alu, full_preds, iu_vvv_ops)
DEF_RVV_FUNCTION (vor, alu, full_preds, iu_vvv_ops)
DEF_RVV_FUNCTION (vxor, alu, full_preds, iu_vvv_ops)
DEF_RVV_FUNCTION (vsll, alu, full_preds, iu_shift_vvv_ops)
-DEF_RVV_FUNCTION (vsra, alu, full_preds, iu_shift_vvv_ops)
-DEF_RVV_FUNCTION (vsrl, alu, full_preds, iu_shift_vvv_ops)
+DEF_RVV_FUNCTION (vsra, alu, full_preds, i_shift_vvv_ops)
+DEF_RVV_FUNCTION (vsrl, alu, full_preds, u_shift_vvv_ops)
DEF_RVV_FUNCTION (vmin, alu, full_preds, i_vvv_ops)
DEF_RVV_FUNCTION (vmax, alu, full_preds, i_vvv_ops)
DEF_RVV_FUNCTION (vminu, alu, full_preds, u_vvv_ops)
@@ -90,8 +90,8 @@ DEF_RVV_FUNCTION (vand, alu, full_preds, iu_vvx_ops)
DEF_RVV_FUNCTION (vor, alu, full_preds, iu_vvx_ops)
DEF_RVV_FUNCTION (vxor, alu, full_preds, iu_vvx_ops)
DEF_RVV_FUNCTION (vsll, alu, full_preds, iu_shift_vvx_ops)
-DEF_RVV_FUNCTION (vsra, alu, full_preds, iu_shift_vvx_ops)
-DEF_RVV_FUNCTION (vsrl, alu, full_preds, iu_shift_vvx_ops)
+DEF_RVV_FUNCTION (vsra, alu, full_preds, i_shift_vvx_ops)
+DEF_RVV_FUNCTION (vsrl, alu, full_preds, u_shift_vvx_ops)
DEF_RVV_FUNCTION (vmin, alu, full_preds, i_vvx_ops)
DEF_RVV_FUNCTION (vmax, alu, full_preds, i_vvx_ops)
DEF_RVV_FUNCTION (vminu, alu, full_preds, u_vvx_ops)
@@ -148,6 +148,15 @@ DEF_RVV_FUNCTION (vmadc, return_mask, none_preds, iu_mvv_ops)
DEF_RVV_FUNCTION (vmsbc, return_mask, none_preds, iu_mvv_ops)
DEF_RVV_FUNCTION (vmadc, return_mask, none_preds, iu_mvx_ops)
DEF_RVV_FUNCTION (vmsbc, return_mask, none_preds, iu_mvx_ops)
+DEF_RVV_FUNCTION (vnsrl, narrow_alu, full_preds, u_narrow_shift_vwv_ops)
+DEF_RVV_FUNCTION (vnsra, narrow_alu, full_preds, i_narrow_shift_vwv_ops)
+DEF_RVV_FUNCTION (vnsrl, narrow_alu, full_preds, u_narrow_shift_vwx_ops)
+DEF_RVV_FUNCTION (vnsra, narrow_alu, full_preds, i_narrow_shift_vwx_ops)
+DEF_RVV_FUNCTION (vncvt_x, narrow_alu, full_preds, iu_trunc_ops)
+DEF_RVV_FUNCTION (vmerge, no_mask_policy, tu_preds, all_vvvm_ops)
+DEF_RVV_FUNCTION (vmerge, no_mask_policy, tu_preds, iu_vvxm_ops)
+DEF_RVV_FUNCTION (vmv_v, move, tu_preds, all_v_ops)
+DEF_RVV_FUNCTION (vmv_v, move, tu_preds, iu_x_ops)
/* 12. Vector Fixed-Point Arithmetic Instructions. */
DEF_RVV_FUNCTION (vsadd, alu, full_preds, i_vvv_ops)
DEF_RVV_FUNCTION (vssub, alu, full_preds, i_vvv_ops)
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
index dae515cb5c3..e1d8f4f13f0 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
@@ -293,6 +293,58 @@ struct return_mask_def : public build_base
}
};
+/* narrow_alu_def class. Handle narrowing instructions like vnsrl.wv. */
+struct narrow_alu_def : public build_base
+{
+ char *get_name (function_builder &b, const function_instance &instance,
+ bool overloaded_p) const override
+ {
+ b.append_base_name (instance.base_name);
+
+ if (!overloaded_p)
+ {
+ /* vop --> vop_<op>. */
+ b.append_name (operand_suffixes[instance.op_info->op]);
+ /* vop_<op> --> vop_<op>_<type>. */
+ vector_type_index ret_type_idx
+ = instance.op_info->ret.get_base_vector_type (
+ builtin_types[instance.type.index].vector);
+ b.append_name (type_suffixes[ret_type_idx].vector);
+ }
+
+ /* According to rvv-intrinsic-doc, it does not add "_m" suffix
+ for vop_m C++ overloaded API. */
+ if (overloaded_p && instance.pred == PRED_TYPE_m)
+ return b.finish_name ();
+ b.append_name (predication_suffixes[instance.pred]);
+ return b.finish_name ();
+ }
+};
+
+/* move_def class. Handle vmv.v.v/vmv.v.x. */
+struct move_def : public build_base
+{
+ char *get_name (function_builder &b, const function_instance &instance,
+ bool overloaded_p) const override
+ {
+ /* vmv.v.x (PRED_none) can not be overloaded. */
+ if (instance.op_info->op == OP_TYPE_x && overloaded_p
+ && instance.pred == PRED_TYPE_none)
+ return nullptr;
+
+ b.append_base_name (instance.base_name);
+
+ if (!overloaded_p)
+ {
+ b.append_name (operand_suffixes[instance.op_info->op]);
+ b.append_name (type_suffixes[instance.type.index].vector);
+ }
+
+ b.append_name (predication_suffixes[instance.pred]);
+ return b.finish_name ();
+ }
+};
+
SHAPE(vsetvl, vsetvl)
SHAPE(vsetvl, vsetvlmax)
SHAPE(loadstore, loadstore)
@@ -301,5 +353,7 @@ SHAPE(alu, alu)
SHAPE(widen_alu, widen_alu)
SHAPE(no_mask_policy, no_mask_policy)
SHAPE(return_mask, return_mask)
+SHAPE(narrow_alu, narrow_alu)
+SHAPE(move, move)
} // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.h b/gcc/config/riscv/riscv-vector-builtins-shapes.h
index 783b4712a45..91c174f56cd 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.h
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h
@@ -32,6 +32,8 @@ extern const function_shape *const alu;
extern const function_shape *const widen_alu;
extern const function_shape *const no_mask_policy;
extern const function_shape *const return_mask;
+extern const function_shape *const narrow_alu;
+extern const function_shape *const move;
}
} // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index ce62baec5ce..e937edbf536 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -202,6 +202,14 @@ static const rvv_type_info wextu_ops[] = {
#include "riscv-vector-builtins-types.def"
{NUM_VECTOR_TYPES, 0}};
+/* A list of Double-Widening all integer will be registered for intrinsic
+ * functions. */
+static const rvv_type_info wextiu_ops[] = {
+#define DEF_RVV_WEXTI_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#define DEF_RVV_WEXTU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+ {NUM_VECTOR_TYPES, 0}};
+
/* A list of Quad-Widening unsigned integer will be registered for intrinsic
* functions. */
static const rvv_type_info qextu_ops[] = {
@@ -340,10 +348,21 @@ static CONSTEXPR const rvv_arg_type_info shift_vv_args[]
= {rvv_arg_type_info (RVV_BASE_vector),
rvv_arg_type_info (RVV_BASE_shift_vector), rvv_arg_type_info_end};
+/* A list of args for double demote type func (vector_type, shift_type)
+ * function. */
+static CONSTEXPR const rvv_arg_type_info shift_wv_args[]
+ = {rvv_arg_type_info (RVV_BASE_vector),
+ rvv_arg_type_info (RVV_BASE_double_trunc_unsigned_vector),
+ rvv_arg_type_info_end};
+
/* A list of args for vector_type func (vector_type) function. */
static CONSTEXPR const rvv_arg_type_info v_args[]
= {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info_end};
+/* A list of args for vector_type func (scalar_type) function. */
+static CONSTEXPR const rvv_arg_type_info x_args[]
+ = {rvv_arg_type_info (RVV_BASE_scalar), rvv_arg_type_info_end};
+
/* A list of args for vector_type func (vector_type, size) function. */
static CONSTEXPR const rvv_arg_type_info vector_size_args[]
= {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_size),
@@ -562,6 +581,14 @@ static CONSTEXPR const rvv_op_info iu_vvvm_ops
rvv_arg_type_info (RVV_BASE_vector), /* Return type */
vvm_args /* Args */};
+/* A static operand information for vector_type func (vector_type, vector_type,
+ * mask_type) function registration. */
+static CONSTEXPR const rvv_op_info all_vvvm_ops
+ = {all_ops, /* Types */
+ OP_TYPE_vvm, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ vvm_args /* Args */};
+
/* A static operand information for vector_type func (vector_type, scalar_type,
* mask_type) function registration. */
static CONSTEXPR const rvv_op_info iu_vvxm_ops
@@ -707,6 +734,38 @@ static CONSTEXPR const rvv_op_info iu_shift_vvx_ops
rvv_arg_type_info (RVV_BASE_vector), /* Return type */
vector_size_args /* Args */};
+/* A static operand information for vector_type func (vector_type, shift_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info i_shift_vvv_ops
+ = {i_ops, /* Types */
+ OP_TYPE_vv, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ shift_vv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, size_t)
+ * function registration. */
+static CONSTEXPR const rvv_op_info i_shift_vvx_ops
+ = {i_ops, /* Types */
+ OP_TYPE_vx, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ vector_size_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, shift_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_shift_vvv_ops
+ = {u_ops, /* Types */
+ OP_TYPE_vv, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ shift_vv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, size_t)
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_shift_vvx_ops
+ = {u_ops, /* Types */
+ OP_TYPE_vx, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ vector_size_args /* Args */};
+
/* A static operand information for vector_type func (vector_type)
* function registration. */
static CONSTEXPR const rvv_op_info iu_v_ops
@@ -715,6 +774,22 @@ static CONSTEXPR const rvv_op_info iu_v_ops
rvv_arg_type_info (RVV_BASE_vector), /* Return type */
v_args /* Args */};
+/* A static operand information for vector_type func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info all_v_ops
+ = {all_ops, /* Types */
+ OP_TYPE_v, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ v_args /* Args */};
+
+/* A static operand information for vector_type func (scalar_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info iu_x_ops
+ = {iu_ops, /* Types */
+ OP_TYPE_x, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ x_args /* Args */};
+
/* A static operand information for vector_type func (double demote type)
* function registration. */
static CONSTEXPR const rvv_op_info i_vf2_ops
@@ -859,6 +934,46 @@ static CONSTEXPR const rvv_op_info u_x_x_v_ops
rvv_arg_type_info (RVV_BASE_vector), /* Return type */
x_x_v_args /* Args */};
+/* A static operand information for double demote type func (vector_type,
+ * shift_type) function registration. */
+static CONSTEXPR const rvv_op_info i_narrow_shift_vwv_ops
+ = {wexti_ops, /* Types */
+ OP_TYPE_wv, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */
+ shift_wv_args /* Args */};
+
+/* A static operand information for double demote type func (vector_type,
+ * shift_type) function registration. */
+static CONSTEXPR const rvv_op_info u_narrow_shift_vwv_ops
+ = {wextu_ops, /* Types */
+ OP_TYPE_wv, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */
+ shift_wv_args /* Args */};
+
+/* A static operand information for double demote type func (vector_type,
+ * size_t) function registration. */
+static CONSTEXPR const rvv_op_info i_narrow_shift_vwx_ops
+ = {wexti_ops, /* Types */
+ OP_TYPE_wx, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */
+ vector_size_args /* Args */};
+
+/* A static operand information for double demote type func (vector_type,
+ * size_t) function registration. */
+static CONSTEXPR const rvv_op_info u_narrow_shift_vwx_ops
+ = {wextu_ops, /* Types */
+ OP_TYPE_wx, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */
+ vector_size_args /* Args */};
+
+/* A static operand information for double demote type func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info iu_trunc_ops
+ = {wextiu_ops, /* Types */
+ OP_TYPE_x_w, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_double_trunc_vector), /* Return type */
+ v_args /* Args */};
+
/* A list of all RVV intrinsic functions. */
static function_group_info function_groups[] = {
#define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO) \
diff --git a/gcc/config/riscv/riscv-vector-builtins.def b/gcc/config/riscv/riscv-vector-builtins.def
index 9f4cd011404..baafed8a4e9 100644
--- a/gcc/config/riscv/riscv-vector-builtins.def
+++ b/gcc/config/riscv/riscv-vector-builtins.def
@@ -279,9 +279,8 @@ DEF_RVV_OP_TYPE (vf4)
DEF_RVV_OP_TYPE (vf8)
DEF_RVV_OP_TYPE (vvm)
DEF_RVV_OP_TYPE (vxm)
-DEF_RVV_OP_TYPE (x_x_w)
-DEF_RVV_OP_TYPE (v_v)
-DEF_RVV_OP_TYPE (v_x)
+DEF_RVV_OP_TYPE (x_w)
+DEF_RVV_OP_TYPE (x)
DEF_RVV_OP_TYPE (vs)
DEF_RVV_OP_TYPE (mm)
DEF_RVV_OP_TYPE (m)
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 3b7804b7501..a282c7c6494 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -4229,17 +4229,45 @@ riscv_print_operand (FILE *file, rtx op, int letter)
switch (letter)
{
+ case 'o': {
+ /* Print 'OP' variant for RVV instructions.
+ 1. If the operand is VECTOR REG, we print 'v'(vnsrl.wv).
+ 2. If the operand is CONST_INT/CONST_VECTOR, we print 'i'(vnsrl.wi).
+ 3. If the operand is SCALAR REG, we print 'x'(vnsrl.wx). */
+ if (riscv_v_ext_vector_mode_p (mode))
+ {
+ if (REG_P (op))
+ asm_fprintf (file, "v");
+ else if (CONST_VECTOR_P (op))
+ asm_fprintf (file, "i");
+ else
+ output_operand_lossage ("invalid vector operand");
+ }
+ else
+ {
+ if (CONST_INT_P (op))
+ asm_fprintf (file, "i");
+ else
+ asm_fprintf (file, "x");
+ }
+ break;
+ }
case 'v': {
rtx elt;
- if (!const_vec_duplicate_p (op, &elt))
- output_operand_lossage ("invalid vector constant");
- else if (satisfies_constraint_Wc0 (op))
- asm_fprintf (file, "0");
- else if (satisfies_constraint_vi (op))
- asm_fprintf (file, "%wd", INTVAL (elt));
+ if (REG_P (op))
+ asm_fprintf (file, "%s", reg_names[REGNO (op)]);
else
- output_operand_lossage ("invalid vector constant");
+ {
+ if (!const_vec_duplicate_p (op, &elt))
+ output_operand_lossage ("invalid vector constant");
+ else if (satisfies_constraint_Wc0 (op))
+ asm_fprintf (file, "0");
+ else if (satisfies_constraint_vi (op))
+ asm_fprintf (file, "%wd", INTVAL (elt));
+ else
+ output_operand_lossage ("invalid vector constant");
+ }
break;
}
case 'V': {
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 6b255c4ddb3..e76ad21140b 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -289,6 +289,9 @@
(define_code_iterator any_widen_binop [plus minus mult])
(define_code_iterator plus_minus [plus minus])
+(define_code_attr macc_nmsac [(plus "macc") (minus "nmsac")])
+(define_code_attr madd_nmsub [(plus "madd") (minus "nmsub")])
+
(define_code_attr binop_rhs1_predicate [
(plus "register_operand")
(minus "vector_arith_operand")
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index b3f8c055a75..976f82e7514 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -144,7 +144,8 @@
(define_attr "ratio" ""
(cond [(eq_attr "type" "vimov,vfmov,vldux,vldox,vstux,vstox,\
vialu,vshift,vicmp,vimul,vidiv,vsalu,\
- vext,viwalu,viwmul,vicalu")
+ vext,viwalu,viwmul,vicalu,vnshift,\
+ vimuladd,vimerge")
(const_int INVALID_ATTRIBUTE)
(eq_attr "mode" "VNx1QI,VNx1BI")
(symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)")
@@ -195,8 +196,12 @@
;; The index of operand[] to get the merge op.
(define_attr "merge_op_idx" ""
(cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu,vldux,vldox,\
- vialu,vshift,vicmp,vimul,vidiv,vsalu,vext,viwalu,viwmul")
- (const_int 2)]
+ vialu,vshift,vicmp,vimul,vidiv,vsalu,vext,viwalu,\
+ viwmul,vnshift,vimuladd")
+ (const_int 2)
+
+ (eq_attr "type" "vimerge")
+ (const_int 1)]
(const_int INVALID_ATTRIBUTE)))
;; The index of operand[] to get the avl op.
@@ -213,7 +218,7 @@
(const_int 4))
(eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\
- viwalu,viwmul")
+ viwalu,viwmul,vnshift,vimuladd,vimerge")
(const_int 5)]
(const_int INVALID_ATTRIBUTE)))
@@ -230,7 +235,7 @@
(symbol_ref "riscv_vector::get_ta(operands[5])"))
(eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\
- viwalu,viwmul")
+ viwalu,viwmul,vnshift,vimuladd,vimerge")
(symbol_ref "riscv_vector::get_ta(operands[6])")]
(const_int INVALID_ATTRIBUTE)))
@@ -247,13 +252,13 @@
(symbol_ref "riscv_vector::get_ma(operands[6])"))
(eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\
- viwalu,viwmul")
+ viwalu,viwmul,vnshift,vimuladd")
(symbol_ref "riscv_vector::get_ma(operands[7])")]
(const_int INVALID_ATTRIBUTE)))
;; The avl type value.
(define_attr "avl_type" ""
- (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov,vext")
+ (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov,vext,vimerge")
(symbol_ref "INTVAL (operands[7])")
(eq_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
(symbol_ref "INTVAL (operands[5])")
@@ -266,7 +271,7 @@
(symbol_ref "INTVAL (operands[7])"))
(eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\
- viwalu,viwmul")
+ viwalu,viwmul,vnshift,vimuladd")
(symbol_ref "INTVAL (operands[8])")
(eq_attr "type" "vstux,vstox")
(symbol_ref "INTVAL (operands[5])")]
@@ -659,6 +664,7 @@
;; -------------------------------------------------------------------------------
;; Includes:
;; - 7.4. Vector Unit-Stride Instructions
+;; - 11.15 Vector Integer Merge Instructions
;; - 11.16 Vector Integer Move Instructions
;; - 13.16 Vector Floating-Point Move Instruction
;; - 15.1 Vector Mask-Register Logical Instructions
@@ -720,7 +726,8 @@
vmv.v.i\t%0,%v3"
"&& register_operand (operands[0], <MODE>mode)
&& register_operand (operands[3], <MODE>mode)
- && satisfies_constraint_vu (operands[2])"
+ && satisfies_constraint_vu (operands[2])
+ && INTVAL (operands[7]) == riscv_vector::VLMAX"
[(set (match_dup 0) (match_dup 3))]
""
[(set_attr "type" "vlde,vlde,vlde,vste,vimov,vimov")
@@ -794,6 +801,134 @@
(set (attr "avl_type") (symbol_ref "riscv_vector::NONVLMAX"))
(set_attr "vl_op_idx" "3")])
+(define_insn "@pred_merge<mode>"
+ [(set (match_operand:V 0 "register_operand" "=vd, vd")
+ (if_then_else:V
+ (match_operand:<VM> 4 "register_operand" " vm, vm")
+ (if_then_else:V
+ (unspec:<VM>
+ [(match_dup 4)
+ (match_operand 5 "vector_length_operand" " rK, rK")
+ (match_operand 6 "const_int_operand" " i, i")
+ (match_operand 7 "const_int_operand" " i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (match_operand:V 3 "vector_arith_operand" " vr, vi")
+ (match_operand:V 2 "register_operand" " vr, vr"))
+ (match_operand:V 1 "vector_merge_operand" " 0vu, 0vu")))]
+ "TARGET_VECTOR"
+ "vmerge.v%o3m\t%0,%2,%v3,%4"
+ [(set_attr "type" "vimerge")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_merge<mode>_scalar"
+ [(set (match_operand:VI_QHS 0 "register_operand" "=vd")
+ (if_then_else:VI_QHS
+ (match_operand:<VM> 4 "register_operand" " vm")
+ (if_then_else:VI_QHS
+ (unspec:<VM>
+ [(match_dup 4)
+ (match_operand 5 "vector_length_operand" " rK")
+ (match_operand 6 "const_int_operand" " i")
+ (match_operand 7 "const_int_operand" " i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (vec_duplicate:VI_QHS
+ (match_operand:<VEL> 3 "register_operand" " r"))
+ (match_operand:VI_QHS 2 "register_operand" " vr"))
+ (match_operand:VI_QHS 1 "vector_merge_operand" "0vu")))]
+ "TARGET_VECTOR"
+ "vmerge.vxm\t%0,%2,%3,%4"
+ [(set_attr "type" "vimerge")
+ (set_attr "mode" "<MODE>")])
+
+(define_expand "@pred_merge<mode>_scalar"
+ [(set (match_operand:VI_D 0 "register_operand")
+ (if_then_else:VI_D
+ (match_operand:<VM> 4 "register_operand")
+ (if_then_else:VI_D
+ (unspec:<VM>
+ [(match_dup 4)
+ (match_operand 5 "vector_length_operand")
+ (match_operand 6 "const_int_operand")
+ (match_operand 7 "const_int_operand")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (vec_duplicate:VI_D
+ (match_operand:<VEL> 3 "reg_or_int_operand"))
+ (match_operand:VI_D 2 "register_operand"))
+ (match_operand:VI_D 1 "vector_merge_operand")))]
+ "TARGET_VECTOR"
+ {
+ if (riscv_vector::neg_simm5_p (operands[3]))
+ operands[3] = force_reg (<VEL>mode, operands[3]);
+ else if (!TARGET_64BIT)
+ {
+ rtx v = gen_reg_rtx (<MODE>mode);
+
+ if (riscv_vector::simm32_p (operands[3]))
+ operands[3] = gen_rtx_SIGN_EXTEND (<VEL>mode,
+ force_reg (Pmode, operands[3]));
+ else
+ {
+ if (CONST_INT_P (operands[3]))
+ operands[3] = force_reg (<VEL>mode, operands[3]);
+
+ riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (<MODE>mode),
+ v, operands[3], operands[5], <VM>mode);
+ emit_insn (gen_pred_merge<mode> (operands[0], operands[1],
+ operands[2], v, operands[4],operands[5],
+ operands[6], operands[7]));
+ DONE;
+ }
+ }
+ else
+ operands[3] = force_reg (<VEL>mode, operands[3]);
+ })
+
+(define_insn "*pred_merge<mode>_scalar"
+ [(set (match_operand:VI_D 0 "register_operand" "=vd")
+ (if_then_else:VI_D
+ (match_operand:<VM> 4 "register_operand" " vm")
+ (if_then_else:VI_D
+ (unspec:<VM>
+ [(match_dup 4)
+ (match_operand 5 "vector_length_operand" " rK")
+ (match_operand 6 "const_int_operand" " i")
+ (match_operand 7 "const_int_operand" " i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (vec_duplicate:VI_D
+ (match_operand:<VEL> 3 "register_operand" " r"))
+ (match_operand:VI_D 2 "register_operand" " vr"))
+ (match_operand:VI_D 1 "vector_merge_operand" "0vu")))]
+ "TARGET_VECTOR"
+ "vmerge.vxm\t%0,%2,%3,%4"
+ [(set_attr "type" "vimerge")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*pred_merge<mode>_extended_scalar"
+ [(set (match_operand:VI_D 0 "register_operand" "=vd")
+ (if_then_else:VI_D
+ (match_operand:<VM> 4 "register_operand" " vm")
+ (if_then_else:VI_D
+ (unspec:<VM>
+ [(match_dup 4)
+ (match_operand 5 "vector_length_operand" " rK")
+ (match_operand 6 "const_int_operand" " i")
+ (match_operand 7 "const_int_operand" " i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (vec_duplicate:VI_D
+ (sign_extend:<VEL>
+ (match_operand:<VSUBEL> 3 "register_operand" " r")))
+ (match_operand:VI_D 2 "register_operand" " vr"))
+ (match_operand:VI_D 1 "vector_merge_operand" "0vu")))]
+ "TARGET_VECTOR"
+ "vmerge.vxm\t%0,%2,%3,%4"
+ [(set_attr "type" "vimerge")
+ (set_attr "mode" "<MODE>")])
+
;; -------------------------------------------------------------------------------
;; ---- Predicated Broadcast
;; -------------------------------------------------------------------------------
@@ -823,7 +958,7 @@
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
(vec_duplicate:V
- (match_operand:<VEL> 3 "direct_broadcast_operand" "Wbr, f, Wdm, Wdm"))
+ (match_operand:<VEL> 3 "direct_broadcast_operand" " r, f, Wdm, Wdm"))
(match_operand:V 2 "vector_merge_operand" "0vu, 0vu, 0vu, 0vu")))]
"TARGET_VECTOR"
"@
@@ -1227,11 +1362,7 @@
(match_operand 4 "pmode_reg_or_uimm5_operand" " r, r, K, K"))
(match_operand:VI 2 "vector_merge_operand" "0vu,0vu,0vu,0vu")))]
"TARGET_VECTOR"
- "@
- v<insn>.vx\t%0,%3,%4%p1
- v<insn>.vx\t%0,%3,%4%p1
- v<insn>.vi\t%0,%3,%4%p1
- v<insn>.vi\t%0,%3,%4%p1"
+ "v<insn>.v%o4\t%0,%3,%4%p1"
[(set_attr "type" "vshift")
(set_attr "mode" "<MODE>")])
@@ -1957,9 +2088,7 @@
(match_operand:<VM> 4 "register_operand" " vm, vm")] UNSPEC_VADC)
(match_operand:VI 1 "vector_merge_operand" " 0vu, 0vu")))]
"TARGET_VECTOR"
- "@
- vadc.vvm\t%0,%2,%3,%4
- vadc.vim\t%0,%2,%v3,%4"
+ "vadc.v%o3m\t%0,%2,%v3,%4"
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "merge_op_idx" "1")
@@ -2250,9 +2379,7 @@
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMADC))]
"TARGET_VECTOR"
- "@
- vmadc.vvm\t%0,%1,%2,%3
- vmadc.vim\t%0,%1,%v2,%3"
+ "vmadc.v%o2m\t%0,%1,%v2,%3"
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "4")
@@ -2497,9 +2624,7 @@
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))]
"TARGET_VECTOR"
- "@
- vmadc.vv\t%0,%1,%2
- vmadc.vi\t%0,%1,%v2"
+ "vmadc.v%o2\t%0,%1,%v2"
[(set_attr "type" "vicalu")
(set_attr "mode" "<MODE>")
(set_attr "vl_op_idx" "3")
@@ -2754,7 +2879,7 @@
(set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
;; -------------------------------------------------------------------------------
-;; ---- Predicated integer widening operations
+;; ---- Predicated integer widening binary operations
;; -------------------------------------------------------------------------------
;; Includes:
;; - 11.2 Vector Widening Integer Add/Subtract
@@ -2982,3 +3107,79 @@
(set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])"))
(set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
(set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+
+;; -------------------------------------------------------------------------------
+;; ---- Predicated integer Narrowing operations
+;; -------------------------------------------------------------------------------
+;; Includes:
+;; - 11.7 Vector Narrowing Integer Right Shift Instructions
+;; -------------------------------------------------------------------------------
+
+;; The destination EEW is smaller than the source EEW and the overlap is in the
+;; lowest-numbered part of the source register group
+;; e.g, when LMUL = 1, vnsrl.wi v0,v0,3 is legal but a destination of v1 is not.
+(define_insn "@pred_narrow_<optab><mode>"
+ [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand" "=vd, vr, &vr, vd, vr, &vr")
+ (if_then_else:<V_DOUBLE_TRUNC>
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vmWc1, vm,Wc1,vmWc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (truncate:<V_DOUBLE_TRUNC>
+ (any_shiftrt:VWEXTI
+ (match_operand:VWEXTI 3 "register_operand" " 0, 0, vr, 0, 0, vr")
+ (match_operand:<V_DOUBLE_TRUNC> 4 "vector_shift_operand" " vr, vr, vr, vk, vk, vk")))
+ (match_operand:<V_DOUBLE_TRUNC> 2 "vector_merge_operand" "0vu,0vu, 0vu,0vu,0vu, 0vu")))]
+ "TARGET_VECTOR"
+ "vn<insn>.w%o4\t%0,%3,%v4%p1"
+ [(set_attr "type" "vnshift")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+(define_insn "@pred_narrow_<optab><mode>_scalar"
+ [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand" "=vd, vr, &vr, vd, vr, &vr")
+ (if_then_else:<V_DOUBLE_TRUNC>
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vmWc1, vm,Wc1,vmWc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (truncate:<V_DOUBLE_TRUNC>
+ (any_shiftrt:VWEXTI
+ (match_operand:VWEXTI 3 "register_operand" " 0, 0, vr, 0, 0, vr")
+ (match_operand 4 "pmode_reg_or_uimm5_operand" " r, r, r, K, K, K")))
+ (match_operand:<V_DOUBLE_TRUNC> 2 "vector_merge_operand" "0vu,0vu, 0vu,0vu,0vu, 0vu")))]
+ "TARGET_VECTOR"
+ "vn<insn>.w%o4\t%0,%3,%4%p1"
+ [(set_attr "type" "vnshift")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+;; vncvt.x.x.w
+(define_insn "@pred_trunc<mode>"
+ [(set (match_operand:<V_DOUBLE_TRUNC> 0 "register_operand" "=vd, vr, &vr")
+ (if_then_else:<V_DOUBLE_TRUNC>
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vmWc1")
+ (match_operand 4 "vector_length_operand" " rK, rK, rK")
+ (match_operand 5 "const_int_operand" " i, i, i")
+ (match_operand 6 "const_int_operand" " i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (truncate:<V_DOUBLE_TRUNC>
+ (match_operand:VWEXTI 3 "register_operand" " 0, 0, vr"))
+ (match_operand:<V_DOUBLE_TRUNC> 2 "vector_merge_operand" "0vu,0vu, 0vu")))]
+ "TARGET_VECTOR"
+ "vncvt.x.x.w\t%0,%3%p1"
+ [(set_attr "type" "vnshift")
+ (set_attr "mode" "<V_DOUBLE_TRUNC>")
+ (set_attr "vl_op_idx" "4")
+ (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])"))
+ (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])"))
+ (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
More information about the Gcc-cvs
mailing list