[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