public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] RISC-V: Add vmadc/vsbc C/C++ API support
@ 2023-02-08 20:52 juzhe.zhong
  0 siblings, 0 replies; only message in thread
From: juzhe.zhong @ 2023-02-08 20:52 UTC (permalink / raw)
  To: gcc-patches; +Cc: kito.cheng, Ju-Zhe Zhong

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

gcc/ChangeLog:

        * config/riscv/riscv-vector-builtins-bases.cc (class vmadc): New class.
        (class vmsbc): Ditto.
        (BASE): Define new class.
        * config/riscv/riscv-vector-builtins-bases.h: Ditto.
        * config/riscv/riscv-vector-builtins-functions.def (vmadc): New define.
        (vmsbc): Ditto.
        * config/riscv/riscv-vector-builtins-shapes.cc (struct return_mask_def): New class.
        (SHAPE): Ditto.
        * config/riscv/riscv-vector-builtins-shapes.h: Ditto.
        * config/riscv/riscv-vector-builtins.cc (function_expander::use_exact_insn): Adjust for new support
        * config/riscv/riscv-vector-builtins.h (function_base::has_merge_operand_p): New function.
        * config/riscv/vector-iterators.md: New iterator.
        * config/riscv/vector.md (@pred_madc<mode>): New pattern.
        (@pred_msbc<mode>): Ditto.
        (@pred_madc<mode>_scalar): Ditto.
        (@pred_msbc<mode>_scalar): Ditto.
        (*pred_madc<mode>_scalar): Ditto.
        (*pred_madc<mode>_extended_scalar): Ditto.
        (*pred_msbc<mode>_scalar): Ditto.
        (*pred_msbc<mode>_extended_scalar): Ditto.
        (@pred_madc<mode>_overflow): Ditto.
        (@pred_msbc<mode>_overflow): Ditto.
        (@pred_madc<mode>_overflow_scalar): Ditto.
        (@pred_msbc<mode>_overflow_scalar): Ditto.
        (*pred_madc<mode>_overflow_scalar): Ditto.
        (*pred_madc<mode>_overflow_extended_scalar): Ditto.
        (*pred_msbc<mode>_overflow_scalar): Ditto.
        (*pred_msbc<mode>_overflow_extended_scalar): Ditto.

---
 .../riscv/riscv-vector-builtins-bases.cc      |  62 +++
 .../riscv/riscv-vector-builtins-bases.h       |   2 +
 .../riscv/riscv-vector-builtins-functions.def |   8 +
 .../riscv/riscv-vector-builtins-shapes.cc     |  28 +
 .../riscv/riscv-vector-builtins-shapes.h      |   1 +
 gcc/config/riscv/riscv-vector-builtins.cc     |  34 +-
 gcc/config/riscv/riscv-vector-builtins.h      |  11 +
 gcc/config/riscv/vector-iterators.md          |   3 +
 gcc/config/riscv/vector.md                    | 494 ++++++++++++++++++
 9 files changed, 642 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index 8bf5bb97ca1..bcf2dfe805a 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -338,6 +338,64 @@ public:
   }
 };
 
+/* Implements vmadc.  */
+class vmadc : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+  bool use_mask_predication_p () const override { return false; }
+  bool has_merge_operand_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_madc (e.vector_mode ()));
+      case OP_TYPE_vxm:
+	return e.use_exact_insn (code_for_pred_madc_scalar (e.vector_mode ()));
+      case OP_TYPE_vv:
+	return e.use_exact_insn (
+	  code_for_pred_madc_overflow (e.vector_mode ()));
+      case OP_TYPE_vx:
+	return e.use_exact_insn (
+	  code_for_pred_madc_overflow_scalar (e.vector_mode ()));
+      default:
+	gcc_unreachable ();
+      }
+  }
+};
+
+/* Implements vmsbc.  */
+class vmsbc : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+  bool use_mask_predication_p () const override { return false; }
+  bool has_merge_operand_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_msbc (e.vector_mode ()));
+      case OP_TYPE_vxm:
+	return e.use_exact_insn (code_for_pred_msbc_scalar (e.vector_mode ()));
+      case OP_TYPE_vv:
+	return e.use_exact_insn (
+	  code_for_pred_msbc_overflow (e.vector_mode ()));
+      case OP_TYPE_vx:
+	return e.use_exact_insn (
+	  code_for_pred_msbc_overflow_scalar (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;
@@ -398,6 +456,8 @@ static CONSTEXPR const vwcvt<SIGN_EXTEND> vwcvt_x_obj;
 static CONSTEXPR const vwcvt<ZERO_EXTEND> vwcvtu_x_obj;
 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 binop<SS_PLUS> vsadd_obj;
 static CONSTEXPR const binop<SS_MINUS> vssub_obj;
 static CONSTEXPR const binop<US_PLUS> vsaddu_obj;
@@ -468,6 +528,8 @@ BASE (vwcvt_x)
 BASE (vwcvtu_x)
 BASE (vadc)
 BASE (vsbc)
+BASE (vmadc)
+BASE (vmsbc)
 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 729c069c1eb..6a8747b184e 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.h
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.h
@@ -84,6 +84,8 @@ extern const function_base *const vwcvt_x;
 extern const function_base *const vwcvtu_x;
 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 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 3d8db35683b..6d328537ab8 100644
--- a/gcc/config/riscv/riscv-vector-builtins-functions.def
+++ b/gcc/config/riscv/riscv-vector-builtins-functions.def
@@ -140,6 +140,14 @@ DEF_RVV_FUNCTION (vadc, no_mask_policy, tu_preds, iu_vvvm_ops)
 DEF_RVV_FUNCTION (vsbc, no_mask_policy, tu_preds, iu_vvvm_ops)
 DEF_RVV_FUNCTION (vadc, no_mask_policy, tu_preds, iu_vvxm_ops)
 DEF_RVV_FUNCTION (vsbc, no_mask_policy, tu_preds, iu_vvxm_ops)
+DEF_RVV_FUNCTION (vmadc, return_mask, none_preds, iu_mvvm_ops)
+DEF_RVV_FUNCTION (vmsbc, return_mask, none_preds, iu_mvvm_ops)
+DEF_RVV_FUNCTION (vmadc, return_mask, none_preds, iu_mvxm_ops)
+DEF_RVV_FUNCTION (vmsbc, return_mask, none_preds, iu_mvxm_ops)
+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)
 /* 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 91870077a0c..dae515cb5c3 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
@@ -266,6 +266,33 @@ struct no_mask_policy_def : public build_base
   }
 };
 
+/* return_mask_def class. Such instructions belong to this class
+   is returning mask value.  */
+struct return_mask_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)
+      b.append_name (operand_suffixes[instance.op_info->op]);
+
+    /* vop<sew>_<op> --> vop<sew>_<op>_<type1>_<type2>.  */
+    if (!overloaded_p)
+      {
+	b.append_name (type_suffixes[instance.type.index].vector);
+	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);
+      }
+
+    b.append_name (predication_suffixes[instance.pred]);
+    return b.finish_name ();
+  }
+};
+
 SHAPE(vsetvl, vsetvl)
 SHAPE(vsetvl, vsetvlmax)
 SHAPE(loadstore, loadstore)
@@ -273,5 +300,6 @@ SHAPE(indexed_loadstore, indexed_loadstore)
 SHAPE(alu, alu)
 SHAPE(widen_alu, widen_alu)
 SHAPE(no_mask_policy, no_mask_policy)
+SHAPE(return_mask, return_mask)
 
 } // 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 6aadde3df6c..783b4712a45 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.h
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h
@@ -31,6 +31,7 @@ extern const function_shape *const indexed_loadstore;
 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;
 }
 
 } // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index afdc3c4c6d6..00cb721d408 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -570,6 +570,38 @@ static CONSTEXPR const rvv_op_info iu_vvxm_ops
      rvv_arg_type_info (RVV_BASE_vector), /* Return type */
      vxm_args /* Args */};
 
+/* A static operand information for mask_type func (vector_type, vector_type,
+ * mask_type) function registration. */
+static CONSTEXPR const rvv_op_info iu_mvvm_ops
+  = {iu_ops,				  /* Types */
+     OP_TYPE_vvm,			  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_mask), /* Return type */
+     vvm_args /* Args */};
+
+/* A static operand information for mask_type func (vector_type, scalar_type,
+ * mask_type) function registration. */
+static CONSTEXPR const rvv_op_info iu_mvxm_ops
+  = {iu_ops,				  /* Types */
+     OP_TYPE_vxm,			  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_mask), /* Return type */
+     vxm_args /* Args */};
+
+/* A static operand information for mask_type func (vector_type, vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info iu_mvv_ops
+  = {iu_ops,				/* Types */
+     OP_TYPE_vv,			/* Suffix */
+     rvv_arg_type_info (RVV_BASE_mask), /* Return type */
+     vv_args /* Args */};
+
+/* A static operand information for mask_type func (vector_type, scalar_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info iu_mvx_ops
+  = {iu_ops,				/* Types */
+     OP_TYPE_vx,			/* Suffix */
+     rvv_arg_type_info (RVV_BASE_mask), /* Return type */
+     vx_args /* Args */};
+
 /* A static operand information for vector_type func (vector_type, vector_type)
  * function registration. */
 static CONSTEXPR const rvv_op_info i_vvv_ops
@@ -1670,7 +1702,7 @@ function_expander::use_exact_insn (insn_code icode)
     }
 
   /* Store operation doesn't have merge operand.  */
-  if (!function_returns_void_p ())
+  if (!function_returns_void_p () && base->has_merge_operand_p ())
     {
       if (use_real_merge_p (pred))
 	add_input_operand (arg_offset++);
diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
index 4f78c299e6f..f00b2c51020 100644
--- a/gcc/config/riscv/riscv-vector-builtins.h
+++ b/gcc/config/riscv/riscv-vector-builtins.h
@@ -388,6 +388,9 @@ public:
   /* Return true if intrinsics use mask predication.  */
   virtual bool use_mask_predication_p () const;
 
+  /* Return true if intrinsics has merge operand.  */
+  virtual bool has_merge_operand_p () const;
+
   /* Expand the given call into rtl.  Return the result of the function,
      or an arbitrary value if the function doesn't return a result.  */
   virtual rtx expand (function_expander &) const = 0;
@@ -521,6 +524,14 @@ function_base::use_mask_predication_p () const
   return true;
 }
 
+/* We choose to return true by default since most of the intrinsics use
+   has merge operand.  */
+inline bool
+function_base::has_merge_operand_p () const
+{
+  return true;
+}
+
 /* Since most of intrinsics can be overloaded, we set it true by default.  */
 inline bool
 function_base::can_be_overloaded_p (enum predication_type_index) const
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index c3f3f1b01f8..6b255c4ddb3 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -36,6 +36,9 @@
 
   UNSPEC_VADC
   UNSPEC_VSBC
+  UNSPEC_VMADC
+  UNSPEC_VMSBC
+  UNSPEC_OVERFLOW
 ])
 
 (define_mode_iterator V [
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 7da95013156..b3d4eb79193 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -1962,6 +1962,7 @@
    vadc.vim\t%0,%2,%v3,%4"
   [(set_attr "type" "vicalu")
    (set_attr "mode" "<MODE>")
+   (set_attr "merge_op_idx" "1")
    (set_attr "vl_op_idx" "5")
    (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
@@ -1985,6 +1986,7 @@
   "vsbc.vvm\t%0,%2,%3,%4"
   [(set_attr "type" "vicalu")
    (set_attr "mode" "<MODE>")
+   (set_attr "merge_op_idx" "1")
    (set_attr "vl_op_idx" "5")
    (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
@@ -2009,6 +2011,7 @@
   "vadc.vxm\t%0,%2,%3,%4"
   [(set_attr "type" "vicalu")
    (set_attr "mode" "<MODE>")
+   (set_attr "merge_op_idx" "1")
    (set_attr "vl_op_idx" "5")
    (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
@@ -2033,6 +2036,7 @@
   "vsbc.vxm\t%0,%2,%z3,%4"
   [(set_attr "type" "vicalu")
    (set_attr "mode" "<MODE>")
+   (set_attr "merge_op_idx" "1")
    (set_attr "vl_op_idx" "5")
    (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
@@ -2102,6 +2106,7 @@
   "vadc.vxm\t%0,%2,%3,%4"
   [(set_attr "type" "vicalu")
    (set_attr "mode" "<MODE>")
+   (set_attr "merge_op_idx" "1")
    (set_attr "vl_op_idx" "5")
    (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
@@ -2127,6 +2132,7 @@
   "vadc.vxm\t%0,%2,%3,%4"
   [(set_attr "type" "vicalu")
    (set_attr "mode" "<MODE>")
+   (set_attr "merge_op_idx" "1")
    (set_attr "vl_op_idx" "5")
    (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
@@ -2200,6 +2206,7 @@
   "vsbc.vxm\t%0,%2,%z3,%4"
   [(set_attr "type" "vicalu")
    (set_attr "mode" "<MODE>")
+   (set_attr "merge_op_idx" "1")
    (set_attr "vl_op_idx" "5")
    (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
@@ -2225,10 +2232,497 @@
   "vsbc.vxm\t%0,%2,%z3,%4"
   [(set_attr "type" "vicalu")
    (set_attr "mode" "<MODE>")
+   (set_attr "merge_op_idx" "1")
    (set_attr "vl_op_idx" "5")
    (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[6])"))
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
 
+(define_insn "@pred_madc<mode>"
+  [(set (match_operand:<VM> 0 "register_operand"        "=&vr, &vr")
+	(unspec:<VM>
+	   [(plus:VI
+	     (match_operand:VI 1 "register_operand"     "  vr,  vr")
+	     (match_operand:VI 2 "vector_arith_operand" "  vr,  vi"))
+	    (match_operand:<VM> 3 "register_operand"    "  vm,  vm")
+	    (unspec:<VM>
+	      [(match_operand 4 "vector_length_operand" "  rK,  rK")
+	       (match_operand 5 "const_int_operand"     "   i,   i")
+	       (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"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "4")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+
+(define_insn "@pred_msbc<mode>"
+  [(set (match_operand:<VM> 0 "register_operand"        "=&vr")
+	(unspec:<VM>
+	   [(minus:VI
+	     (match_operand:VI 1 "register_operand"     "  vr")
+	     (match_operand:VI 2 "register_operand"     "  vr"))
+	    (match_operand:<VM> 3 "register_operand"    "  vm")
+	    (unspec:<VM>
+	      [(match_operand 4 "vector_length_operand" "  rK")
+	       (match_operand 5 "const_int_operand"     "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMSBC))]
+  "TARGET_VECTOR"
+  "vmsbc.vvm\t%0,%1,%2,%3"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "4")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+
+(define_insn "@pred_madc<mode>_scalar"
+  [(set (match_operand:<VM> 0 "register_operand"         "=&vr")
+	(unspec:<VM>
+	   [(plus:VI_QHS
+	     (vec_duplicate:VI_QHS
+	       (match_operand:<VEL> 2 "register_operand" "   r"))
+	     (match_operand:VI_QHS 1 "register_operand"  "  vr"))
+	    (match_operand:<VM> 3 "register_operand"     "  vm")
+	    (unspec:<VM>
+	      [(match_operand 4 "vector_length_operand"  "  rK")
+	       (match_operand 5 "const_int_operand"      "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMADC))]
+  "TARGET_VECTOR"
+  "vmadc.vxm\t%0,%1,%2,%3"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "4")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+
+(define_insn "@pred_msbc<mode>_scalar"
+  [(set (match_operand:<VM> 0 "register_operand"         "=&vr")
+	(unspec:<VM>
+	   [(minus:VI_QHS
+	     (vec_duplicate:VI_QHS
+	       (match_operand:<VEL> 2 "reg_or_0_operand" "  rJ"))
+	     (match_operand:VI_QHS 1 "register_operand"  "  vr"))
+	    (match_operand:<VM> 3 "register_operand"     "  vm")
+	    (unspec:<VM>
+	      [(match_operand 4 "vector_length_operand"  "  rK")
+	       (match_operand 5 "const_int_operand"      "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMSBC))]
+  "TARGET_VECTOR"
+  "vmsbc.vxm\t%0,%1,%z2,%3"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "4")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+
+(define_expand "@pred_madc<mode>_scalar"
+  [(set (match_operand:<VM> 0 "register_operand")
+	(unspec:<VM>
+	   [(plus:VI_D
+	     (vec_duplicate:VI_D
+	       (match_operand:<VEL> 2 "reg_or_int_operand"))
+	     (match_operand:VI_D 1 "register_operand"))
+	    (match_operand:<VM> 3 "register_operand")
+	    (unspec:<VM>
+	      [(match_operand 4 "vector_length_operand")
+	       (match_operand 5 "const_int_operand")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMADC))]
+  "TARGET_VECTOR"
+  {
+    if (riscv_vector::simm5_p (operands[2]))
+      operands[2] = force_reg (<VEL>mode, operands[2]);
+    else if (!TARGET_64BIT)
+      {
+        rtx v = gen_reg_rtx (<MODE>mode);
+
+	if (riscv_vector::simm32_p (operands[2]))
+	  operands[2] = gen_rtx_SIGN_EXTEND (<VEL>mode,
+		force_reg (Pmode, operands[2]));
+        else
+  	  {
+  	    if (CONST_INT_P (operands[2]))
+  	      operands[2] = force_reg (<VEL>mode, operands[2]);
+
+  	    riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (<MODE>mode),
+  	  				    v, operands[2], operands[5],
+  	  				    <VM>mode);
+  	    emit_insn (gen_pred_madc<mode> (operands[0], operands[1], v, operands[3],
+  	  				    operands[4], operands[5]));
+  	    DONE;
+  	  }
+      }
+    else
+      operands[2] = force_reg (<VEL>mode, operands[2]);
+  })
+
+(define_insn "*pred_madc<mode>_scalar"
+  [(set (match_operand:<VM> 0 "register_operand"         "=&vr")
+	(unspec:<VM>
+	   [(plus:VI_D
+	     (vec_duplicate:VI_D
+	       (match_operand:<VEL> 2 "register_operand" "   r"))
+	     (match_operand:VI_D 1 "register_operand"    "  vr"))
+	    (match_operand:<VM> 3 "register_operand"     "  vm")
+	    (unspec:<VM>
+	      [(match_operand 4 "vector_length_operand"  "  rK")
+	       (match_operand 5 "const_int_operand"      "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMADC))]
+  "TARGET_VECTOR"
+  "vmadc.vxm\t%0,%1,%2,%3"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "4")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+
+(define_insn "*pred_madc<mode>_extended_scalar"
+  [(set (match_operand:<VM> 0 "register_operand"             "=&vr")
+	(unspec:<VM>
+	   [(plus:VI_D
+	     (vec_duplicate:VI_D
+	       (sign_extend:<VEL>
+	         (match_operand:<VSUBEL> 2 "register_operand" "   r")))
+	     (match_operand:VI_D 1 "register_operand"         "  vr"))
+	    (match_operand:<VM> 3 "register_operand"          "  vm")
+	    (unspec:<VM>
+	      [(match_operand 4 "vector_length_operand"       "  rK")
+	       (match_operand 5 "const_int_operand"           "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMADC))]
+  "TARGET_VECTOR"
+  "vmadc.vxm\t%0,%1,%2,%3"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "4")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+
+(define_expand "@pred_msbc<mode>_scalar"
+  [(set (match_operand:<VM> 0 "register_operand")
+	(unspec:<VM>
+	   [(minus:VI_D
+	     (vec_duplicate:VI_D
+	       (match_operand:<VEL> 2 "reg_or_int_operand"))
+	     (match_operand:VI_D 1 "register_operand"))
+	    (match_operand:<VM> 3 "register_operand")
+	    (unspec:<VM>
+	      [(match_operand 4 "vector_length_operand")
+	       (match_operand 5 "const_int_operand")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMSBC))]
+  "TARGET_VECTOR"
+  {
+    if (!TARGET_64BIT)
+      {
+        rtx v = gen_reg_rtx (<MODE>mode);
+
+	if (riscv_vector::simm32_p (operands[2]))
+	  {
+	    if (!rtx_equal_p (operands[2], const0_rtx))
+	      operands[2] = force_reg (Pmode, operands[2]);
+	    operands[2] = gen_rtx_SIGN_EXTEND (<VEL>mode, operands[2]);
+	  }
+        else
+  	  {
+  	    if (CONST_INT_P (operands[2]))
+  	      operands[2] = force_reg (<VEL>mode, operands[2]);
+
+  	    riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (<MODE>mode),
+  	  				    v, operands[2], operands[5],
+  	  				    <VM>mode);
+  	    emit_insn (gen_pred_msbc<mode> (operands[0], operands[1], v, operands[3],
+  	  				    operands[4], operands[5]));
+  	    DONE;
+  	  }
+      }
+    else
+      {
+	if (!rtx_equal_p (operands[2], const0_rtx))
+	  operands[2] = force_reg (<VEL>mode, operands[2]);
+      }
+  })
+
+(define_insn "*pred_msbc<mode>_scalar"
+  [(set (match_operand:<VM> 0 "register_operand"         "=&vr")
+	(unspec:<VM>
+	   [(minus:VI_D
+	     (vec_duplicate:VI_D
+	       (match_operand:<VEL> 2 "reg_or_0_operand" "  rJ"))
+	     (match_operand:VI_D 1 "register_operand"    "  vr"))
+	    (match_operand:<VM> 3 "register_operand"     "  vm")
+	    (unspec:<VM>
+	      [(match_operand 4 "vector_length_operand"  "  rK")
+	       (match_operand 5 "const_int_operand"      "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMSBC))]
+  "TARGET_VECTOR"
+  "vmsbc.vxm\t%0,%1,%z2,%3"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "4")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+
+(define_insn "*pred_msbc<mode>_extended_scalar"
+  [(set (match_operand:<VM> 0 "register_operand"             "=&vr")
+	(unspec:<VM>
+	   [(minus:VI_D
+	     (vec_duplicate:VI_D
+	       (sign_extend:<VEL>
+	         (match_operand:<VSUBEL> 2 "reg_or_0_operand" "  rJ")))
+	     (match_operand:VI_D 1 "register_operand"         "  vr"))
+	    (match_operand:<VM> 3 "register_operand"          "  vm")
+	    (unspec:<VM>
+	      [(match_operand 4 "vector_length_operand"       "  rK")
+	       (match_operand 5 "const_int_operand"           "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_VMSBC))]
+  "TARGET_VECTOR"
+  "vmsbc.vxm\t%0,%1,%z2,%3"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "4")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+
+(define_insn "@pred_madc<mode>_overflow"
+  [(set (match_operand:<VM> 0 "register_operand"        "=&vr, &vr")
+	(unspec:<VM>
+	   [(plus:VI
+	     (match_operand:VI 1 "register_operand"     "  vr,  vr")
+	     (match_operand:VI 2 "vector_arith_operand" "  vr,  vi"))
+	    (unspec:<VM>
+	      [(match_operand 3 "vector_length_operand" "  rK,  rK")
+	       (match_operand 4 "const_int_operand"     "   i,   i")
+	       (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"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "3")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+
+(define_insn "@pred_msbc<mode>_overflow"
+  [(set (match_operand:<VM> 0 "register_operand"        "=&vr")
+	(unspec:<VM>
+	   [(minus:VI
+	     (match_operand:VI 1 "register_operand"     "  vr")
+	     (match_operand:VI 2 "register_operand"     "  vr"))
+	    (unspec:<VM>
+	      [(match_operand 3 "vector_length_operand" "  rK")
+	       (match_operand 4 "const_int_operand"     "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))]
+  "TARGET_VECTOR"
+  "vmsbc.vv\t%0,%1,%2"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "3")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+
+(define_insn "@pred_madc<mode>_overflow_scalar"
+  [(set (match_operand:<VM> 0 "register_operand"         "=&vr")
+	(unspec:<VM>
+	   [(plus:VI_QHS
+	     (vec_duplicate:VI_QHS
+	       (match_operand:<VEL> 2 "register_operand" "   r"))
+	     (match_operand:VI_QHS 1 "register_operand"  "  vr"))
+	    (unspec:<VM>
+	      [(match_operand 3 "vector_length_operand"  "  rK")
+	       (match_operand 4 "const_int_operand"      "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))]
+  "TARGET_VECTOR"
+  "vmadc.vx\t%0,%1,%2"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "3")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+
+(define_insn "@pred_msbc<mode>_overflow_scalar"
+  [(set (match_operand:<VM> 0 "register_operand"         "=&vr")
+	(unspec:<VM>
+	   [(minus:VI_QHS
+	     (vec_duplicate:VI_QHS
+	       (match_operand:<VEL> 2 "reg_or_0_operand" "  rJ"))
+	     (match_operand:VI_QHS 1 "register_operand"  "  vr"))
+	    (unspec:<VM>
+	      [(match_operand 3 "vector_length_operand"  "  rK")
+	       (match_operand 4 "const_int_operand"      "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))]
+  "TARGET_VECTOR"
+  "vmsbc.vx\t%0,%1,%z2"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "3")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+
+(define_expand "@pred_madc<mode>_overflow_scalar"
+  [(set (match_operand:<VM> 0 "register_operand")
+	(unspec:<VM>
+	   [(plus:VI_D
+	     (vec_duplicate:VI_D
+	       (match_operand:<VEL> 2 "reg_or_int_operand"))
+	     (match_operand:VI_D 1 "register_operand"))
+	    (unspec:<VM>
+	      [(match_operand 3 "vector_length_operand")
+	       (match_operand 4 "const_int_operand")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))]
+  "TARGET_VECTOR"
+  {
+    if (riscv_vector::simm5_p (operands[2]))
+      operands[2] = force_reg (<VEL>mode, operands[2]);
+    else if (!TARGET_64BIT)
+      {
+        rtx v = gen_reg_rtx (<MODE>mode);
+
+	if (riscv_vector::simm32_p (operands[2]))
+	  operands[2] = gen_rtx_SIGN_EXTEND (<VEL>mode,
+		force_reg (Pmode, operands[2]));
+        else
+  	  {
+  	    if (CONST_INT_P (operands[2]))
+  	      operands[2] = force_reg (<VEL>mode, operands[2]);
+
+  	    riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (<MODE>mode),
+  	  				    v, operands[2], operands[3],
+  	  				    <VM>mode);
+  	    emit_insn (gen_pred_madc<mode>_overflow (operands[0], operands[1],
+						     v, operands[3], operands[4]));
+  	    DONE;
+  	  }
+      }
+    else
+      operands[2] = force_reg (<VEL>mode, operands[2]);
+  })
+
+(define_insn "*pred_madc<mode>_overflow_scalar"
+  [(set (match_operand:<VM> 0 "register_operand"         "=&vr")
+	(unspec:<VM>
+	   [(plus:VI_D
+	     (vec_duplicate:VI_D
+	       (match_operand:<VEL> 2 "register_operand" "   r"))
+	     (match_operand:VI_D 1 "register_operand"    "  vr"))
+	    (unspec:<VM>
+	      [(match_operand 3 "vector_length_operand"  "  rK")
+	       (match_operand 4 "const_int_operand"      "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))]
+  "TARGET_VECTOR"
+  "vmadc.vx\t%0,%1,%2"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "3")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+
+(define_insn "*pred_madc<mode>_overflow_extended_scalar"
+  [(set (match_operand:<VM> 0 "register_operand"             "=&vr")
+	(unspec:<VM>
+	   [(plus:VI_D
+	     (vec_duplicate:VI_D
+	       (sign_extend:<VEL>
+	         (match_operand:<VSUBEL> 2 "register_operand" "   r")))
+	     (match_operand:VI_D 1 "register_operand"         "  vr"))
+	    (unspec:<VM>
+	      [(match_operand 3 "vector_length_operand"       "  rK")
+	       (match_operand 4 "const_int_operand"           "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))]
+  "TARGET_VECTOR"
+  "vmadc.vx\t%0,%1,%2"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "3")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+
+(define_expand "@pred_msbc<mode>_overflow_scalar"
+  [(set (match_operand:<VM> 0 "register_operand")
+	(unspec:<VM>
+	   [(minus:VI_D
+	     (vec_duplicate:VI_D
+	       (match_operand:<VEL> 2 "reg_or_int_operand"))
+	     (match_operand:VI_D 1 "register_operand"))
+	    (unspec:<VM>
+	      [(match_operand 3 "vector_length_operand")
+	       (match_operand 4 "const_int_operand")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))]
+  "TARGET_VECTOR"
+  {
+    if (!TARGET_64BIT)
+      {
+        rtx v = gen_reg_rtx (<MODE>mode);
+
+	if (riscv_vector::simm32_p (operands[2]))
+	  {
+	    if (!rtx_equal_p (operands[2], const0_rtx))
+	      operands[2] = force_reg (Pmode, operands[2]);
+	    operands[2] = gen_rtx_SIGN_EXTEND (<VEL>mode, operands[2]);
+	  }
+        else
+  	  {
+  	    if (CONST_INT_P (operands[2]))
+  	      operands[2] = force_reg (<VEL>mode, operands[2]);
+
+  	    riscv_vector::emit_nonvlmax_op (code_for_pred_broadcast (<MODE>mode),
+  	  				    v, operands[2], operands[3],
+  	  				    <VM>mode);
+  	    emit_insn (gen_pred_msbc<mode>_overflow (operands[0], operands[1],
+						     v, operands[3], operands[4]));
+  	    DONE;
+  	  }
+      }
+    else
+      {
+	if (!rtx_equal_p (operands[2], const0_rtx))
+	  operands[2] = force_reg (<VEL>mode, operands[2]);
+      }
+  })
+
+(define_insn "*pred_msbc<mode>_overflow_scalar"
+  [(set (match_operand:<VM> 0 "register_operand"         "=&vr")
+	(unspec:<VM>
+	   [(minus:VI_D
+	     (vec_duplicate:VI_D
+	       (match_operand:<VEL> 2 "reg_or_0_operand" "  rJ"))
+	     (match_operand:VI_D 1 "register_operand"    "  vr"))
+	    (unspec:<VM>
+	      [(match_operand 3 "vector_length_operand"  "  rK")
+	       (match_operand 4 "const_int_operand"      "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))]
+  "TARGET_VECTOR"
+  "vmsbc.vx\t%0,%1,%z2"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "3")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+
+(define_insn "*pred_msbc<mode>_overflow_extended_scalar"
+  [(set (match_operand:<VM> 0 "register_operand"             "=&vr")
+	(unspec:<VM>
+	   [(minus:VI_D
+	     (vec_duplicate:VI_D
+	       (sign_extend:<VEL>
+	         (match_operand:<VSUBEL> 2 "reg_or_0_operand" "  rJ")))
+	     (match_operand:VI_D 1 "register_operand"         "  vr"))
+	    (unspec:<VM>
+	      [(match_operand 3 "vector_length_operand"       "  rK")
+	       (match_operand 4 "const_int_operand"           "   i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)] UNSPEC_OVERFLOW))]
+  "TARGET_VECTOR"
+  "vmsbc.vx\t%0,%1,%z2"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (set_attr "vl_op_idx" "3")
+   (set (attr "avl_type") (symbol_ref "INTVAL (operands[4])"))])
+
 ;; -------------------------------------------------------------------------------
 ;; ---- Predicated integer unary operations
 ;; -------------------------------------------------------------------------------
-- 
2.36.3


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

only message in thread, other threads:[~2023-02-08 20:52 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-08 20:52 [PATCH] RISC-V: Add vmadc/vsbc C/C++ API 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).