public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] RISC-V: Add vadc/vsbc C/C++ API support
@ 2023-02-08  2:30 juzhe.zhong
  0 siblings, 0 replies; only message in thread
From: juzhe.zhong @ 2023-02-08  2:30 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-protos.h (simm5_p): Add vadc/vsbc support.
        * config/riscv/riscv-v.cc (simm32_p): Ditto.
        * config/riscv/riscv-vector-builtins-bases.cc (class vadc): New class.
        (class vsbc): Ditto.
        (BASE): Ditto.
        * config/riscv/riscv-vector-builtins-bases.h: Ditto.
        * config/riscv/riscv-vector-builtins-functions.def (vadc): Ditto.
        (vsbc): Ditto.
        * config/riscv/riscv-vector-builtins-shapes.cc (struct no_mask_policy_def): Ditto.
        (SHAPE): Ditto.
        * config/riscv/riscv-vector-builtins-shapes.h: Ditto.
        * config/riscv/riscv-vector-builtins.cc (rvv_arg_type_info::get_base_vector_type): Add vadc/vsbc support.
        (rvv_arg_type_info::get_tree_type): Ditto.
        (function_expander::use_exact_insn): Ditto.
        * config/riscv/riscv-vector-builtins.h (enum rvv_base_type): Ditto.
        (function_base::use_mask_predication_p): New function.
        * config/riscv/vector-iterators.md: New iterator.
        * config/riscv/vector.md (@pred_adc<mode>): New pattern.
        (@pred_sbc<mode>): Ditto.
        (@pred_adc<mode>_scalar): Ditto.
        (@pred_sbc<mode>_scalar): Ditto.
        (*pred_adc<mode>_scalar): Ditto.
        (*pred_adc<mode>_extended_scalar): Ditto.
        (*pred_sbc<mode>_scalar): Ditto.
        (*pred_sbc<mode>_extended_scalar): Ditto.

---
 gcc/config/riscv/riscv-protos.h               |   1 +
 gcc/config/riscv/riscv-v.cc                   |   2 +-
 .../riscv/riscv-vector-builtins-bases.cc      |  46 +++
 .../riscv/riscv-vector-builtins-bases.h       |   2 +
 .../riscv/riscv-vector-builtins-functions.def |   4 +
 .../riscv/riscv-vector-builtins-shapes.cc     |  22 ++
 .../riscv/riscv-vector-builtins-shapes.h      |   1 +
 gcc/config/riscv/riscv-vector-builtins.cc     |  50 ++-
 gcc/config/riscv/riscv-vector-builtins.h      |  12 +
 gcc/config/riscv/vector-iterators.md          |   3 +
 gcc/config/riscv/vector.md                    | 295 +++++++++++++++++-
 11 files changed, 430 insertions(+), 8 deletions(-)

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index e090c61a3e3..a4476e6235f 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -175,6 +175,7 @@ enum mask_policy get_prefer_mask_policy ();
 rtx get_avl_type_rtx (enum avl_type);
 opt_machine_mode get_vector_mode (scalar_mode, poly_uint64);
 extern bool simm32_p (rtx);
+extern bool simm5_p (rtx);
 extern bool neg_simm5_p (rtx);
 #ifdef RTX_CODE
 extern bool has_vi_variant_p (rtx_code, rtx);
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index df89c9be308..83cb1f83606 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -408,7 +408,7 @@ simm32_p (rtx x)
   return val <= 0x7FFFFFFFULL || val >= 0xFFFFFFFF80000000ULL;
 }
 
-static bool
+bool
 simm5_p (rtx x)
 {
   if (!CONST_INT_P (x))
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index e14a1854eee..8bf5bb97ca1 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -296,6 +296,48 @@ public:
   }
 };
 
+/* Implements vadc.  */
+class vadc : 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_adc (e.vector_mode ()));
+      case OP_TYPE_vxm:
+	return e.use_exact_insn (code_for_pred_adc_scalar (e.vector_mode ()));
+      default:
+	gcc_unreachable ();
+      }
+  }
+};
+
+/* Implements vsbc.  */
+class vsbc : 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_sbc (e.vector_mode ()));
+      case OP_TYPE_vxm:
+	return e.use_exact_insn (code_for_pred_sbc_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;
@@ -354,6 +396,8 @@ static CONSTEXPR const widen_binop<MULT, ZERO_EXTEND>vwmulu_obj;
 static CONSTEXPR const vwmulsu vwmulsu_obj;
 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 binop<SS_PLUS> vsadd_obj;
 static CONSTEXPR const binop<SS_MINUS> vssub_obj;
 static CONSTEXPR const binop<US_PLUS> vsaddu_obj;
@@ -422,6 +466,8 @@ BASE (vwmulu)
 BASE (vwmulsu)
 BASE (vwcvt_x)
 BASE (vwcvtu_x)
+BASE (vadc)
+BASE (vsbc)
 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 51ec940a5aa..729c069c1eb 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.h
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.h
@@ -82,6 +82,8 @@ extern const function_base *const vwmulu;
 extern const function_base *const vwmulsu;
 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 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 e53fcb5546b..3d8db35683b 100644
--- a/gcc/config/riscv/riscv-vector-builtins-functions.def
+++ b/gcc/config/riscv/riscv-vector-builtins-functions.def
@@ -136,6 +136,10 @@ DEF_RVV_FUNCTION (vwaddu, widen_alu, full_preds, u_wwx_ops)
 DEF_RVV_FUNCTION (vwsubu, widen_alu, full_preds, u_wwx_ops)
 DEF_RVV_FUNCTION (vwcvt_x, alu, full_preds, i_x_x_v_ops)
 DEF_RVV_FUNCTION (vwcvtu_x, alu, full_preds, u_x_x_v_ops)
+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)
 /* 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 62170f607ba..91870077a0c 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
@@ -245,11 +245,33 @@ struct widen_alu_def : public build_base
   }
 };
 
+/* no_mask_policy_def class. Such instructions belong to this class
+   doesn't need mask policy.  */
+struct no_mask_policy_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>_<type>.  */
+    if (!overloaded_p)
+      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)
 SHAPE(indexed_loadstore, indexed_loadstore)
 SHAPE(alu, alu)
 SHAPE(widen_alu, widen_alu)
+SHAPE(no_mask_policy, no_mask_policy)
 
 } // 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 af5474ab36e..6aadde3df6c 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.h
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h
@@ -30,6 +30,7 @@ extern const function_shape *const loadstore;
 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;
 }
 
 } // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 8462c8cdc7d..afdc3c4c6d6 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -306,6 +306,18 @@ static CONSTEXPR const rvv_arg_type_info vv_args[]
   = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_vector),
      rvv_arg_type_info_end};
 
+/* A list of args for vector_type func (vector_type, vector_type, mask_type)
+ * function.  */
+static CONSTEXPR const rvv_arg_type_info vvm_args[]
+  = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_vector),
+     rvv_arg_type_info (RVV_BASE_mask), rvv_arg_type_info_end};
+
+/* A list of args for vector_type func (vector_type, scalar_type, mask_type)
+ * function.  */
+static CONSTEXPR const rvv_arg_type_info vxm_args[]
+  = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_scalar),
+     rvv_arg_type_info (RVV_BASE_mask), rvv_arg_type_info_end};
+
 /* A list of args for vector_type func (signed vector_type, unsigned
  * vector_type) function.  */
 static CONSTEXPR const rvv_arg_type_info su_vv_args[]
@@ -399,6 +411,10 @@ static CONSTEXPR const predication_type_index full_preds[]
   = {PRED_TYPE_none, PRED_TYPE_m,  PRED_TYPE_tu,  PRED_TYPE_tum,
      PRED_TYPE_tumu, PRED_TYPE_mu, NUM_PRED_TYPES};
 
+/* vop/vop_tu will be registered.  */
+static CONSTEXPR const predication_type_index tu_preds[]
+  = {PRED_TYPE_none, PRED_TYPE_tu, NUM_PRED_TYPES};
+
 /* vop/vop_m will be registered.  */
 static CONSTEXPR const predication_type_index none_m_preds[]
   = {PRED_TYPE_none, PRED_TYPE_m, NUM_PRED_TYPES};
@@ -538,6 +554,22 @@ static CONSTEXPR const rvv_op_info iu_vvv_ops
      rvv_arg_type_info (RVV_BASE_vector), /* Return type */
      vv_args /* Args */};
 
+/* A static operand information for vector_type func (vector_type, vector_type,
+ * mask_type) function registration. */
+static CONSTEXPR const rvv_op_info iu_vvvm_ops
+  = {iu_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
+  = {iu_ops,				  /* Types */
+     OP_TYPE_vxm,			  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vxm_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
@@ -1086,6 +1118,9 @@ rvv_arg_type_info::get_base_vector_type (tree type) const
     unsigned_p = true;
   switch (base_type)
     {
+    case RVV_BASE_mask:
+      inner_mode = E_BImode;
+      break;
     case RVV_BASE_uint8_index:
       inner_mode = E_QImode;
       unsigned_p = true;
@@ -1148,7 +1183,8 @@ rvv_arg_type_info::get_base_vector_type (tree type) const
       if (!vector_type)
 	continue;
 
-      if (TYPE_UNSIGNED (vector_type) != unsigned_p)
+      if (GET_MODE_CLASS (TYPE_MODE (vector_type)) != MODE_VECTOR_BOOL
+	  && TYPE_UNSIGNED (vector_type) != unsigned_p)
 	continue;
 
       if (TYPE_MODE (vector_type) == mode.require ())
@@ -1217,6 +1253,7 @@ rvv_arg_type_info::get_tree_type (vector_type_index type_idx) const
     case RVV_BASE_quad_trunc_vector:
     case RVV_BASE_oct_trunc_vector:
     case RVV_BASE_double_trunc_unsigned_vector:
+    case RVV_BASE_mask:
       if (get_base_vector_type (builtin_types[type_idx].vector)
 	  != NUM_VECTOR_TYPES)
 	return builtin_types[get_base_vector_type (
@@ -1624,10 +1661,13 @@ function_expander::use_exact_insn (insn_code icode)
   /* Record the offset to get the argument.  */
   int arg_offset = 0;
 
-  if (use_real_mask_p (pred))
-    add_input_operand (arg_offset++);
-  else
-    add_all_one_mask_operand (mask_mode);
+  if (base->use_mask_predication_p ())
+    {
+      if (use_real_mask_p (pred))
+	add_input_operand (arg_offset++);
+      else
+	add_all_one_mask_operand (mask_mode);
+    }
 
   /* Store operation doesn't have merge operand.  */
   if (!function_returns_void_p ())
diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
index d033a2ea83f..4f78c299e6f 100644
--- a/gcc/config/riscv/riscv-vector-builtins.h
+++ b/gcc/config/riscv/riscv-vector-builtins.h
@@ -140,6 +140,7 @@ enum rvv_base_type
 {
   RVV_BASE_vector,
   RVV_BASE_scalar,
+  RVV_BASE_mask,
   RVV_BASE_unsigned_vector,
   RVV_BASE_unsigned_scalar,
   RVV_BASE_vector_ptr,
@@ -384,6 +385,9 @@ public:
   /* Return true if intrinsic can be overloaded.  */
   virtual bool can_be_overloaded_p (enum predication_type_index) const;
 
+  /* Return true if intrinsics use mask predication.  */
+  virtual bool use_mask_predication_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;
@@ -509,6 +513,14 @@ function_base::apply_mask_policy_p () const
   return true;
 }
 
+/* We choose to return true by default since most of the intrinsics use
+   mask predication.  */
+inline bool
+function_base::use_mask_predication_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 cef9832d583..858415bd6b1 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -33,6 +33,9 @@
   UNSPEC_VMULHS
   UNSPEC_VMULHU
   UNSPEC_VMULHSU
+
+	UNSPEC_VADC
+	UNSPEC_VSBC
 ])
 
 (define_mode_iterator V [
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index d526c1fc5f1..aaac32efcce 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -143,7 +143,8 @@
 ;; It is valid for instruction that require sew/lmul ratio.
 (define_attr "ratio" ""
   (cond [(eq_attr "type" "vimov,vfmov,vldux,vldox,vstux,vstox,\
-			  vialu,vshift,vicmp,vimul,vidiv,vsalu,vext,viwalu,viwmul")
+			  vialu,vshift,vicmp,vimul,vidiv,vsalu,\
+			  vext,viwalu,viwmul,vicalu")
 	   (const_int INVALID_ATTRIBUTE)
 	 (eq_attr "mode" "VNx1QI,VNx1BI")
 	   (symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)")
@@ -764,7 +765,7 @@
   "@
    vlm.v\t%0,%3
    vsm.v\t%3,%0
-   #
+#
    vmclr.m\t%0
    vmset.m\t%0"
   "&& register_operand (operands[0], <MODE>mode)
@@ -1171,6 +1172,7 @@
 ;; -------------------------------------------------------------------------------
 ;; Includes:
 ;; - 11.1 Vector Single-Width Integer Add and Subtract
+;; - 11.4 Vector Integer Add-with-Carry/Subtract-with-Borrow Instructions
 ;; - 11.5 Vector Bitwise Logical Instructions
 ;; - 11.6 Vector Single-Width Bit Shift Instructions
 ;; - 11.9 Vector Integer Min/Max Instructions
@@ -1938,6 +1940,295 @@
   [(set_attr "type" "vimul")
    (set_attr "mode" "<MODE>")])
 
+;; Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
+(define_insn "@pred_adc<mode>"
+  [(set (match_operand:VI 0 "register_operand"            "=&vr, &vr")
+	(if_then_else:VI
+	  (unspec:<VM>
+	    [(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)
+	  (unspec:VI
+	     [(plus:VI
+	       (match_operand:VI 2 "register_operand"     "  vr,  vr")
+	       (match_operand:VI 3 "vector_arith_operand" "  vr,  vi"))
+	     (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"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (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_sbc<mode>"
+  [(set (match_operand:VI 0 "register_operand"            "=&vr")
+	(if_then_else:VI
+	  (unspec:<VM>
+	    [(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)
+	  (unspec:VI
+	     [(minus:VI
+	       (match_operand:VI 2 "register_operand"     "  vr")
+	       (match_operand:VI 3 "register_operand"     "  vr"))
+	      (match_operand:<VM> 4 "register_operand"    "  vm")] UNSPEC_VSBC)
+	  (match_operand:VI 1 "vector_merge_operand"      " 0vu")))]
+  "TARGET_VECTOR"
+  "vsbc.vvm\t%0,%2,%3,%4"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (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_adc<mode>_scalar"
+  [(set (match_operand:VI_QHS 0 "register_operand"        "=&vr")
+	(if_then_else:VI_QHS
+	  (unspec:<VM>
+	    [(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)
+	  (unspec:VI_QHS
+	     [(plus:VI_QHS
+	       (vec_duplicate:VI_QHS
+	         (match_operand:<VEL> 3 "register_operand" "  r"))
+	       (match_operand:VI_QHS 2 "register_operand"  " vr"))
+	     (match_operand:<VM> 4 "register_operand"      " vm")] UNSPEC_VADC)
+	  (match_operand:VI_QHS 1 "vector_merge_operand"   "0vu")))]
+  "TARGET_VECTOR"
+  "vadc.vxm\t%0,%2,%3,%4"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (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_sbc<mode>_scalar"
+  [(set (match_operand:VI_QHS 0 "register_operand"         "=&vr")
+	(if_then_else:VI_QHS
+	  (unspec:<VM>
+	    [(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)
+	  (unspec:VI_QHS
+	     [(minus:VI_QHS
+	        (match_operand:VI_QHS 2 "register_operand" "  vr")
+	        (vec_duplicate:VI_QHS
+	          (match_operand:<VEL> 3 "reg_or_0_operand" " rJ")))
+	      (match_operand:<VM> 4 "register_operand"      " vm")] UNSPEC_VSBC)
+	  (match_operand:VI_QHS 1 "vector_merge_operand"   " 0vu")))]
+  "TARGET_VECTOR"
+  "vsbc.vxm\t%0,%2,%z3,%4"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (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_expand "@pred_adc<mode>_scalar"
+  [(set (match_operand:VI_D 0 "register_operand")
+	(if_then_else:VI_D
+	  (unspec:<VM>
+	    [(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)
+	  (unspec:VI_D
+	     [(plus:VI_D
+	        (vec_duplicate:VI_D
+	          (match_operand:<VEL> 3 "reg_or_int_operand"))
+	        (match_operand:VI_D 2 "register_operand"))
+	      (match_operand:<VM> 4 "register_operand")] UNSPEC_VADC)
+	  (match_operand:VI_D 1 "vector_merge_operand")))]
+  "TARGET_VECTOR"
+  {
+    if (riscv_vector::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_adc<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_adc<mode>_scalar"
+  [(set (match_operand:VI_D 0 "register_operand"           "=&vr")
+	(if_then_else:VI_D
+	  (unspec:<VM>
+	    [(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)
+	  (unspec:VI_D
+	     [(plus:VI_D
+	        (vec_duplicate:VI_D
+	          (match_operand:<VEL> 3 "register_operand" "  r"))
+	        (match_operand:VI_D 2 "register_operand"    " vr"))
+	      (match_operand:<VM> 4 "register_operand"      " vm")] UNSPEC_VADC)
+	  (match_operand:VI_D 1 "vector_merge_operand"      "0vu")))]
+  "TARGET_VECTOR"
+  "vadc.vxm\t%0,%2,%3,%4"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (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_adc<mode>_extended_scalar"
+  [(set (match_operand:VI_D 0 "register_operand"                "=&vr")
+	(if_then_else:VI_D
+	  (unspec:<VM>
+	    [(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)
+	  (unspec:VI_D
+	     [(plus:VI_D
+	        (vec_duplicate:VI_D
+	          (sign_extend:<VEL>
+	            (match_operand:<VSUBEL> 3 "register_operand" "  r")))
+	        (match_operand:VI_D 2 "register_operand"         " vr"))
+	      (match_operand:<VM> 4 "register_operand"           " vm")] UNSPEC_VADC)
+	  (match_operand:VI_D 1 "vector_merge_operand"           "0vu")))]
+  "TARGET_VECTOR"
+  "vadc.vxm\t%0,%2,%3,%4"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (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_expand "@pred_sbc<mode>_scalar"
+  [(set (match_operand:VI_D 0 "register_operand")
+	(if_then_else:VI_D
+	  (unspec:<VM>
+	    [(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)
+	  (unspec:VI_D
+	     [(minus:VI_D
+	        (match_operand:VI_D 2 "register_operand")
+	        (vec_duplicate:VI_D
+	          (match_operand:<VEL> 3 "reg_or_int_operand")))
+	      (match_operand:<VM> 4 "register_operand")] UNSPEC_VSBC)
+	  (match_operand:VI_D 1 "vector_merge_operand")))]
+  "TARGET_VECTOR"
+  {
+    if (!TARGET_64BIT)
+      {
+        rtx v = gen_reg_rtx (<MODE>mode);
+
+	if (riscv_vector::simm32_p (operands[3]))
+	  {
+	    if (!rtx_equal_p (operands[3], const0_rtx))
+	      operands[3] = force_reg (Pmode, operands[3]);
+	    operands[3] = gen_rtx_SIGN_EXTEND (<VEL>mode, 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_sbc<mode> (operands[0], operands[1], operands[2],
+  	  				   v, operands[4], operands[5],
+  	  				   operands[6], operands[7]));
+  	    DONE;
+  	  }
+      }
+    else
+      {
+	if (!rtx_equal_p (operands[3], const0_rtx))
+	  operands[3] = force_reg (<VEL>mode, operands[3]);
+      }
+  })
+
+(define_insn "*pred_sbc<mode>_scalar"
+  [(set (match_operand:VI_D 0 "register_operand"           "=&vr")
+	(if_then_else:VI_D
+	  (unspec:<VM>
+	    [(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)
+	  (unspec:VI_D
+	     [(minus:VI_D
+	        (match_operand:VI_D 2 "register_operand"    " vr")
+	        (vec_duplicate:VI_D
+	          (match_operand:<VEL> 3 "reg_or_0_operand" " rJ")))
+	      (match_operand:<VM> 4 "register_operand"      " vm")] UNSPEC_VSBC)
+	  (match_operand:VI_D 1 "vector_merge_operand"      "0vu")))]
+  "TARGET_VECTOR"
+  "vsbc.vxm\t%0,%2,%z3,%4"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (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_sbc<mode>_extended_scalar"
+  [(set (match_operand:VI_D 0 "register_operand"                "=&vr")
+	(if_then_else:VI_D
+	  (unspec:<VM>
+	    [(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)
+	  (unspec:VI_D
+	     [(minus:VI_D
+	        (match_operand:VI_D 2 "register_operand"         " vr")
+	        (vec_duplicate:VI_D
+	          (sign_extend:<VEL>
+	            (match_operand:<VSUBEL> 3 "reg_or_0_operand" " rJ"))))
+	      (match_operand:<VM> 4 "register_operand"           " vm")] UNSPEC_VSBC)
+	  (match_operand:VI_D 1 "vector_merge_operand"           "0vu")))]
+  "TARGET_VECTOR"
+  "vsbc.vxm\t%0,%2,%z3,%4"
+  [(set_attr "type" "vicalu")
+   (set_attr "mode" "<MODE>")
+   (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])"))])
+
 ;; -------------------------------------------------------------------------------
 ;; ---- Predicated integer unary operations
 ;; -------------------------------------------------------------------------------
-- 
2.36.1


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

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

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