]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Add vnsrl/vnsra/vncvt/vmerge/vmv C/C++ support
authorJu-Zhe Zhong <juzhe.zhong@rivai.ai>
Thu, 9 Feb 2023 21:45:44 +0000 (05:45 +0800)
committerKito Cheng <kito.cheng@sifive.com>
Sun, 12 Feb 2023 07:26:24 +0000 (15:26 +0800)
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.

12 files changed:
gcc/config/riscv/constraints.md
gcc/config/riscv/predicates.md
gcc/config/riscv/riscv-vector-builtins-bases.cc
gcc/config/riscv/riscv-vector-builtins-bases.h
gcc/config/riscv/riscv-vector-builtins-functions.def
gcc/config/riscv/riscv-vector-builtins-shapes.cc
gcc/config/riscv/riscv-vector-builtins-shapes.h
gcc/config/riscv/riscv-vector-builtins.cc
gcc/config/riscv/riscv-vector-builtins.def
gcc/config/riscv/riscv.cc
gcc/config/riscv/vector-iterators.md
gcc/config/riscv/vector.md

index b646ad4853cc53058ca7ec348baa48d14b2c385b..a051d466ae2793ab5c70eb9f70e24d59262d71a5 100644 (file)
   "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))")))
index 8d2ccb0f7a299fcb04d4d2910b9a9ee7313881b7..fe2c5ba3c5c8b4da3015b315a75c7bfb022b59b2 100644 (file)
        (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")
index bcf2dfe805a3ede06070f3f66b783e04ae69a641..30f9734c36b8e46bb1552869436633e89e07ad16 100644 (file)
@@ -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)
index 6a8747b184e667018aa61a81aceb16937703fcdc..411db5627ee9f501356f3ee609fde5d7f44eac45 100644 (file)
@@ -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;
index 6d328537ab8ff556c1e85bfb6b144eb5198ce81f..28483463d644505237c0e0cde86c4899bbefcba2 100644 (file)
@@ -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)
index dae515cb5c3e86ee459ccfc9e481507ba060dde4..e1d8f4f13f005d3f9cd2ec0f31cf6c8cfcacfbf5 100644 (file)
@@ -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
index 783b4712a456d1e3c011cf50afc8f03dd2d6a8d2..91c174f56cde547bef224c0e353d09f9933b12d7 100644 (file)
@@ -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
index ce62baec5ce57eb8273dfa7f9a1a8922c383c983..e937edbf536547eec2b4b82d92f0958ff8ff7bdc 100644 (file)
@@ -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)                         \
index 9f4cd011404c363ffcd522da5f37d76370d11378..baafed8a4e94c475e0a9adc3660092c9c4f98cd7 100644 (file)
@@ -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)
index 3b7804b7501d4ed5a0114bceb20e34381d6cd913..a282c7c6494e39f43f46fad27aaf6b1b920f2bb5 100644 (file)
@@ -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': {
index 6b255c4ddb3e348f01b1ca5fefa5484faf074fff..e76ad21140b27d88ca01ee26a4b66af476b602b5 100644 (file)
 (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")
index b3f8c055a75d98e876edd7be2883069b6b69e72b..976f82e7514ca5d2943b241ec7677ed2669b7868 100644 (file)
 (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)")
 ;; 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.
              (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)))
 
             (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)))
 
             (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])")
             (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])")]
 ;; -------------------------------------------------------------------------------
 ;; 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
    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")
    (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
 ;; -------------------------------------------------------------------------------
             (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"
   "@
            (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>")])
 
             (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")
               (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")
               (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")
    (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
    (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])"))])