public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] RISC-V: Add vnsrl/vnsra/vncvt/vmerge/vmv C/C++ support
@ 2023-02-09 21:45 juzhe.zhong
  0 siblings, 0 replies; only message in thread
From: juzhe.zhong @ 2023-02-09 21:45 UTC (permalink / raw)
  To: gcc-patches; +Cc: kito.cheng, Ju-Zhe Zhong

From: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>

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.

---
 gcc/config/riscv/constraints.md               |  13 -
 gcc/config/riscv/predicates.md                |   7 +-
 .../riscv/riscv-vector-builtins-bases.cc      |  78 ++++++
 .../riscv/riscv-vector-builtins-bases.h       |   5 +
 .../riscv/riscv-vector-builtins-functions.def |  17 +-
 .../riscv/riscv-vector-builtins-shapes.cc     |  54 ++++
 .../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                    | 253 ++++++++++++++++--
 12 files changed, 537 insertions(+), 57 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 00cb721d408..486b8b722b5 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 209d9a53e7b..88a73297ffa 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 b3d4eb79193..cad678369e0 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
@@ -709,7 +715,7 @@
          (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
       (match_operand:V 3 "vector_move_operand"       "    m,     m,     m,    vr,    vr, viWc0")
       (match_operand:V 2 "vector_merge_operand"      "    0,    vu,    vu,    vu,   vu0,   vu0")))]
-  "TARGET_VECTOR && (MEM_P (operands[0]) || MEM_P (operands[3]) 
+  "TARGET_VECTOR && (MEM_P (operands[0]) || MEM_P (operands[3])
    || CONST_VECTOR_P (operands[1]))"
   "@
    vle<sew>.v\t%0,%3%p1
@@ -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])"))])
-- 
2.36.3


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-02-09 21:45 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-09 21:45 [PATCH] RISC-V: Add vnsrl/vnsra/vncvt/vmerge/vmv C/C++ support juzhe.zhong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).