]> gcc.gnu.org Git - gcc.git/commitdiff
RISC-V: Add RVV all mask C/C++ intrinsics support
authorJu-Zhe Zhong <juzhe.zhong@rivai.ai>
Thu, 16 Feb 2023 03:30:01 +0000 (11:30 +0800)
committerKito Cheng <kito.cheng@sifive.com>
Fri, 17 Feb 2023 02:46:35 +0000 (10:46 +0800)
gcc/ChangeLog:

* config/riscv/riscv-vector-builtins-bases.cc (class mask_logic): New
class.
(class mask_nlogic): Ditto.
(class mask_notlogic): Ditto.
(class vmmv): Ditto.
(class vmclr): Ditto.
(class vmset): Ditto.
(class vmnot): Ditto.
(class vcpop): Ditto.
(class vfirst): Ditto.
(class mask_misc): Ditto.
(class viota): Ditto.
(class vid): Ditto.
(BASE): Ditto.
* config/riscv/riscv-vector-builtins-bases.h: Ditto.
* config/riscv/riscv-vector-builtins-functions.def (vmand): Ditto.
(vmnand): Ditto.
(vmandn): Ditto.
(vmxor): Ditto.
(vmor): Ditto.
(vmnor): Ditto.
(vmorn): Ditto.
(vmxnor): Ditto.
(vmmv): Ditto.
(vmclr): Ditto.
(vmset): Ditto.
(vmnot): Ditto.
(vcpop): Ditto.
(vfirst): Ditto.
(vmsbf): Ditto.
(vmsif): Ditto.
(vmsof): Ditto.
(viota): Ditto.
(vid): Ditto.
* config/riscv/riscv-vector-builtins-shapes.cc (struct alu_def): Ditto.
(struct mask_alu_def): Ditto.
(SHAPE): Ditto.
* config/riscv/riscv-vector-builtins-shapes.h: Ditto.
* config/riscv/riscv-vector-builtins.cc: Ditto.
* config/riscv/riscv-vsetvl.cc (pass_vsetvl::cleanup_insns): Fix bug
for dest it scalar RVV intrinsics.
* config/riscv/vector-iterators.md (sof): New iterator.
* config/riscv/vector.md (@pred_<optab>n<mode>): New pattern.
(@pred_<optab>not<mode>): New pattern.
(@pred_popcount<VB:mode><P:mode>): New pattern.
(@pred_ffs<VB:mode><P:mode>): New pattern.
(@pred_<misc_op><mode>): New pattern.
(@pred_iota<mode>): New pattern.
(@pred_series<mode>): New pattern.

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-vsetvl.cc
gcc/config/riscv/vector-iterators.md
gcc/config/riscv/vector.md

index ba7014827281fe1e966a014fb3bfd7b1ceb0257d..88142217e45f5153bf418b3a333e4033910a94c9 100644 (file)
@@ -665,6 +665,185 @@ public:
   }
 };
 
+/* Implements vmand/vmnand/vmandn/vmxor/vmor/vmnor/vmorn/vmxnor  */
+template<rtx_code CODE>
+class mask_logic : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
+  }
+};
+template<rtx_code CODE>
+class mask_nlogic : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_n (CODE, e.vector_mode ()));
+  }
+};
+template<rtx_code CODE>
+class mask_notlogic : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_not (CODE, e.vector_mode ()));
+  }
+};
+
+/* Implements vmmv.  */
+class vmmv : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_mov (e.vector_mode ()));
+  }
+};
+
+/* Implements vmclr.  */
+class vmclr : public function_base
+{
+public:
+  bool can_be_overloaded_p (enum predication_type_index) const override
+  {
+    return false;
+  }
+
+  rtx expand (function_expander &e) const override
+  {
+    machine_mode mode = TYPE_MODE (TREE_TYPE (e.exp));
+    e.add_all_one_mask_operand (mode);
+    e.add_vundef_operand (mode);
+    e.add_input_operand (mode, CONST0_RTX (mode));
+    e.add_input_operand (call_expr_nargs (e.exp) - 1);
+    e.add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
+    return e.generate_insn (code_for_pred_mov (e.vector_mode ()));
+  }
+};
+
+/* Implements vmset.  */
+class vmset : public function_base
+{
+public:
+  bool can_be_overloaded_p (enum predication_type_index) const override
+  {
+    return false;
+  }
+
+  rtx expand (function_expander &e) const override
+  {
+    machine_mode mode = TYPE_MODE (TREE_TYPE (e.exp));
+    e.add_all_one_mask_operand (mode);
+    e.add_vundef_operand (mode);
+    e.add_input_operand (mode, CONSTM1_RTX (mode));
+    e.add_input_operand (call_expr_nargs (e.exp) - 1);
+    e.add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
+    return e.generate_insn (code_for_pred_mov (e.vector_mode ()));
+  }
+};
+
+/* Implements vmnot.  */
+class vmnot : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_not (e.vector_mode ()));
+  }
+};
+
+/* Implements vcpop.  */
+class vcpop : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+  bool has_merge_operand_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_popcount (e.vector_mode (), Pmode));
+  }
+};
+
+/* Implements vfirst.  */
+class vfirst : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+  bool has_merge_operand_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_ffs (e.vector_mode (), Pmode));
+  }
+};
+
+/* Implements vmsbf/vmsif/vmsof.  */
+template<int UNSPEC>
+class mask_misc : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred (UNSPEC, e.vector_mode ()));
+  }
+};
+
+/* Implements viota.  */
+class viota : public function_base
+{
+public:
+  bool can_be_overloaded_p (enum predication_type_index pred) const override
+  {
+    return pred == PRED_TYPE_tu || pred == PRED_TYPE_tum
+          || pred == PRED_TYPE_tumu;
+  }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_iota (e.vector_mode ()));
+  }
+};
+
+/* Implements vid.  */
+class vid : public function_base
+{
+public:
+  bool can_be_overloaded_p (enum predication_type_index pred) const override
+  {
+    return pred == PRED_TYPE_tu || pred == PRED_TYPE_tum
+          || pred == PRED_TYPE_tumu;
+  }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_series (e.vector_mode ()));
+  }
+};
+
 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;
@@ -763,6 +942,25 @@ static CONSTEXPR const sat_op<UNSPEC_VSSRL> vssrl_obj;
 static CONSTEXPR const sat_op<UNSPEC_VSSRA> vssra_obj;
 static CONSTEXPR const vnclip<UNSPEC_VNCLIP> vnclip_obj;
 static CONSTEXPR const vnclip<UNSPEC_VNCLIPU> vnclipu_obj;
+static CONSTEXPR const mask_logic<AND> vmand_obj;
+static CONSTEXPR const mask_nlogic<AND> vmnand_obj;
+static CONSTEXPR const mask_notlogic<AND> vmandn_obj;
+static CONSTEXPR const mask_logic<XOR> vmxor_obj;
+static CONSTEXPR const mask_logic<IOR> vmor_obj;
+static CONSTEXPR const mask_nlogic<IOR> vmnor_obj;
+static CONSTEXPR const mask_notlogic<IOR> vmorn_obj;
+static CONSTEXPR const mask_nlogic<XOR> vmxnor_obj;
+static CONSTEXPR const vmmv vmmv_obj;
+static CONSTEXPR const vmclr vmclr_obj;
+static CONSTEXPR const vmset vmset_obj;
+static CONSTEXPR const vmnot vmnot_obj;
+static CONSTEXPR const vcpop vcpop_obj;
+static CONSTEXPR const vfirst vfirst_obj;
+static CONSTEXPR const mask_misc<UNSPEC_VMSBF> vmsbf_obj;
+static CONSTEXPR const mask_misc<UNSPEC_VMSIF> vmsif_obj;
+static CONSTEXPR const mask_misc<UNSPEC_VMSOF> vmsof_obj;
+static CONSTEXPR const viota viota_obj;
+static CONSTEXPR const vid vid_obj;
 
 /* Declare the function base NAME, pointing it to an instance
    of class <NAME>_obj.  */
@@ -867,5 +1065,24 @@ BASE (vssra)
 BASE (vssrl)
 BASE (vnclip)
 BASE (vnclipu)
+BASE (vmand)
+BASE (vmnand)
+BASE (vmandn)
+BASE (vmxor)
+BASE (vmor)
+BASE (vmnor)
+BASE (vmorn)
+BASE (vmxnor)
+BASE (vmmv)
+BASE (vmclr)
+BASE (vmset)
+BASE (vmnot)
+BASE (vcpop)
+BASE (vfirst)
+BASE (vmsbf)
+BASE (vmsif)
+BASE (vmsof)
+BASE (viota)
+BASE (vid)
 
 } // end namespace riscv_vector
index cb36f1f26996a856b120425d0e46ec7a9d9aefbb..e136cd9114768437c482b71b64be950ae6fc7fa4 100644 (file)
@@ -124,6 +124,25 @@ extern const function_base *const vnclip;
 extern const function_base *const vnclip;
 extern const function_base *const vnclipu;
 extern const function_base *const vnclipu;
+extern const function_base *const vmand;
+extern const function_base *const vmnand;
+extern const function_base *const vmandn;
+extern const function_base *const vmxor;
+extern const function_base *const vmor;
+extern const function_base *const vmnor;
+extern const function_base *const vmorn;
+extern const function_base *const vmxnor;
+extern const function_base *const vmmv;
+extern const function_base *const vmclr;
+extern const function_base *const vmset;
+extern const function_base *const vmnot;
+extern const function_base *const vcpop;
+extern const function_base *const vfirst;
+extern const function_base *const vmsbf;
+extern const function_base *const vmsif;
+extern const function_base *const vmsof;
+extern const function_base *const viota;
+extern const function_base *const vid;
 }
 
 } // end namespace riscv_vector
index e6c19691d177a057d80665d667778694973ded8f..38bf1b694bbbc79ed2bbf1dda2c60ba7b7f5df9c 100644 (file)
@@ -277,7 +277,37 @@ DEF_RVV_FUNCTION (vnclip, narrow_alu, full_preds, i_narrow_shift_vwx_ops)
 
 /* TODO: 13. Vector Floating-Point Instructions.  */
 /* TODO: 14. Vector Reduction Operations.  */
-/* TODO: 15. Vector Mask Instructions.  */
+
+/* 15. Vector Mask Instructions.  */
+
+// 15.1. Vector Mask-Register Logical Instructions
+DEF_RVV_FUNCTION (vmand, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmnand, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmandn, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmxor, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmor, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmnor, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmorn, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmxnor, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmmv, mask_alu, none_preds, b_mm_ops)
+DEF_RVV_FUNCTION (vmclr, mask_alu, none_preds, b_m_ops)
+DEF_RVV_FUNCTION (vmset, mask_alu, none_preds, b_m_ops)
+DEF_RVV_FUNCTION (vmnot, mask_alu, none_preds, b_mm_ops)
+// 15.2. Vector count population in mask vcpop.m
+DEF_RVV_FUNCTION (vcpop, mask_alu, none_m_preds, b_ulong_m_ops)
+// 15.3. vfirst find-first-set mask bit
+DEF_RVV_FUNCTION (vfirst, mask_alu, none_m_preds, b_long_m_ops)
+// 15.4. vmsbf.m set-before-first mask bit
+DEF_RVV_FUNCTION (vmsbf, mask_alu, none_m_mu_preds, b_mm_ops)
+// 15.5. vmsif.m set-including-first mask bit
+DEF_RVV_FUNCTION (vmsif, mask_alu, none_m_mu_preds, b_mm_ops)
+// 15.6. vmsof.m set-only-first mask bit
+DEF_RVV_FUNCTION (vmsof, mask_alu, none_m_mu_preds, b_mm_ops)
+// 15.8. Vector Iota Instruction
+DEF_RVV_FUNCTION (viota, mask_alu, full_preds, u_vm_ops)
+// 15.9. Vector Element Index Instruction
+DEF_RVV_FUNCTION (vid, alu, full_preds, u_v_ops)
+
 /* TODO: 16. Vector Permutation Instructions.  */
 
 #undef DEF_RVV_FUNCTION
index 2836170323aaa1ee73c625dc9572b2c2e2398eda..abf169dea4c51e779e897e63bdb5d9e97aa583ec 100644 (file)
@@ -191,6 +191,10 @@ struct alu_def : public build_base
   char *get_name (function_builder &b, const function_instance &instance,
                  bool overloaded_p) const override
   {
+    /* Return nullptr if it can not be overloaded.  */
+    if (overloaded_p && !instance.base->can_be_overloaded_p (instance.pred))
+      return nullptr;
+
     b.append_base_name (instance.base_name);
 
     /* vop<sew> --> vop<sew>_<op>. According to rvv-intrinsic-doc, _vv/_vx/_v
@@ -342,6 +346,39 @@ struct move_def : public build_base
        b.append_name (type_suffixes[instance.type.index].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 ();
+  }
+};
+
+/* mask_alu_def class.  */
+struct mask_alu_def : public build_base
+{
+  char *get_name (function_builder &b, const function_instance &instance,
+                 bool overloaded_p) const override
+  {
+    /* Return nullptr if it can not be overloaded.  */
+    if (overloaded_p && !instance.base->can_be_overloaded_p (instance.pred))
+      return nullptr;
+
+    b.append_base_name (instance.base_name);
+
+    if (instance.op_info->op == OP_TYPE_mm || instance.op_info->op == OP_TYPE_m)
+      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);
+
+    /* 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 ();
   }
@@ -357,5 +394,6 @@ SHAPE(no_mask_policy, no_mask_policy)
 SHAPE(return_mask, return_mask)
 SHAPE(narrow_alu, narrow_alu)
 SHAPE(move, move)
+SHAPE(mask_alu, mask_alu)
 
 } // end namespace riscv_vector
index 91c174f56cde547bef224c0e353d09f9933b12d7..406abefdb10f5b564c6b2ca7c55575fa30125704 100644 (file)
@@ -34,6 +34,7 @@ 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;
+extern const function_shape *const mask_alu;
 }
 
 } // end namespace riscv_vector
index 4ca5a88cbea1166a1ee8eb5ace42df30b270049e..3747cad672fd400be94ebfd90ce147047b8f7eef 100644 (file)
@@ -231,6 +231,10 @@ static CONSTEXPR const rvv_arg_type_info rvv_arg_type_info_end
 static CONSTEXPR const rvv_arg_type_info void_args[]
   = {rvv_arg_type_info (RVV_BASE_void), rvv_arg_type_info_end};
 
+/* A list of args for size_t func () function.  */
+static CONSTEXPR const rvv_arg_type_info end_args[]
+  = {rvv_arg_type_info_end};
+
 /* A list of args for size_t func (size_t) function.  */
 static CONSTEXPR const rvv_arg_type_info size_args[]
   = {rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end};
@@ -371,6 +375,10 @@ static CONSTEXPR const rvv_arg_type_info shift_wv_args[]
 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 (vector_type) function.  */
+static CONSTEXPR const rvv_arg_type_info m_args[]
+  = {rvv_arg_type_info (RVV_BASE_mask), 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};
@@ -539,6 +547,62 @@ static CONSTEXPR const rvv_op_info b_v_scalar_ptr_ops
      rvv_arg_type_info (RVV_BASE_void), /* Return type */
      scalar_ptr_args /* Args */};
 
+/* A static operand information for vector_type func (vector_type, vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_mmm_ops
+  = {b_ops,                              /* Types */
+     OP_TYPE_mm,                         /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_mm_ops
+  = {b_ops,                              /* Types */
+     OP_TYPE_m,                                  /* Suffix */
+     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 u_vm_ops
+  = {u_ops,                              /* Types */
+     OP_TYPE_m,                                  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     m_args /* Args */};
+
+/* A static operand information for vector_type func ()
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_m_ops
+  = {b_ops,                              /* Types */
+     OP_TYPE_m,                                  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     end_args /* Args */};
+
+/* A static operand information for vector_type func ()
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_v_ops
+  = {u_ops,                              /* Types */
+     OP_TYPE_v,                                  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     end_args /* Args */};
+
+/* A static operand information for unsigned long func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_ulong_m_ops
+  = {b_ops,                                     /* Types */
+     OP_TYPE_m,                                         /* Suffix */
+     rvv_arg_type_info (RVV_BASE_unsigned_long), /* Return type */
+     v_args /* Args */};
+
+/* A static operand information for long func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_long_m_ops
+  = {b_ops,                            /* Types */
+     OP_TYPE_m,                                /* Suffix */
+     rvv_arg_type_info (RVV_BASE_long), /* Return type */
+     v_args /* Args */};
+
 /* A static operand information for vector_type func (const scalar_type *,
  * ptrdiff_t) function registration. */
 static CONSTEXPR const rvv_op_info all_v_scalar_const_ptr_ptrdiff_ops
index 77c62e2d8f35592799bb5a5b0b9ad754f974ddb9..3fbdd8622422c11cc38e4a5bf5c2ede7a0d95869 100644 (file)
@@ -3349,7 +3349,7 @@ pass_vsetvl::cleanup_insns (void) const
          if (!has_vl_op (rinsn) || !REG_P (get_vl (rinsn)))
            continue;
          rtx avl = get_vl (rinsn);
-         if (count_occurrences (PATTERN (rinsn), avl, true) == 1)
+         if (count_occurrences (PATTERN (rinsn), avl, 0) == 1)
            {
              /* Get the list of uses for the new instruction.  */
              auto attempt = crtl->ssa->new_change_attempt ();
@@ -3363,7 +3363,9 @@ pass_vsetvl::cleanup_insns (void) const
              use_array new_uses = use_array (uses_builder.finish ());
              change.new_uses = new_uses;
              change.move_range = insn->ebb ()->insn_range ();
-             rtx pat = simplify_replace_rtx (PATTERN (rinsn), avl, const0_rtx);
+             rtx set = single_set (rinsn);
+             rtx src = simplify_replace_rtx (SET_SRC (set), avl, const0_rtx);
+             rtx pat = gen_rtx_SET (SET_DEST (set), src);
              gcc_assert (change_insn (crtl->ssa, change, insn, pat));
            }
        }
index c8b24150f4e525ebe270f6351d0ed87d6269154a..023b0b329c4296a7079402f9ed1fc0a5f24d520c 100644 (file)
   UNSPEC_VASUBU
   UNSPEC_VASUB
   UNSPEC_VSMUL
+
+  UNSPEC_VMSBF
+  UNSPEC_VMSIF
+  UNSPEC_VMSOF
+  UNSPEC_VIOTA
 ])
 
 (define_mode_iterator V [
                                    UNSPEC_VASUBU UNSPEC_VASUB UNSPEC_VSMUL])
 (define_int_iterator VSAT_SHIFT_OP [UNSPEC_VSSRL UNSPEC_VSSRA])
 
+(define_int_iterator VMISC [UNSPEC_VMSBF UNSPEC_VMSIF UNSPEC_VMSOF])
+
 (define_int_attr order [
   (UNSPEC_ORDERED "o") (UNSPEC_UNORDERED "u")
 ])
                                (UNSPEC_VSSRA "vsshift") (UNSPEC_VNCLIP "vnclip")
                                (UNSPEC_VNCLIPU "vnclip")])
 
+(define_int_attr misc_op [(UNSPEC_VMSBF "sbf") (UNSPEC_VMSIF "sif") (UNSPEC_VMSOF "sof")])
+
 (define_code_iterator any_int_binop [plus minus and ior xor ashift ashiftrt lshiftrt
   smax umax smin umin mult div udiv mod umod
 ])
index c897a365819059b5aea5806ad5ba3f0d1b63e620..c131738c75ff1bb8f4d9848aa333a569800e9660 100644 (file)
                          vialu,vshift,vicmp,vimul,vidiv,vsalu,\
                          vext,viwalu,viwmul,vicalu,vnshift,\
                          vimuladd,vimerge,vaalu,vsmul,vsshift,\
-                         vnclip,viminmax,viwmuladd")
+                         vnclip,viminmax,viwmuladd,vmpop,vmffs,vmsfs,\
+                         vmiota,vmidx")
           (const_int INVALID_ATTRIBUTE)
         (eq_attr "mode" "VNx1QI,VNx1BI")
           (symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)")
 (define_attr "merge_op_idx" ""
        (cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu,vldux,vldox,vicmp,\
                                vialu,vshift,viminmax,vimul,vidiv,vsalu,vext,viwalu,\
-                               viwmul,vnshift,vaalu,vsmul,vsshift,vnclip")
+                               viwmul,vnshift,vaalu,vsmul,vsshift,vnclip,vmsfs,\
+                               vmiota,vmidx")
               (const_int 2)
 
               (eq_attr "type" "vimerge")
 ;; The index of operand[] to get the avl op.
 (define_attr "vl_op_idx" ""
   (cond [(eq_attr "type" "vlde,vste,vimov,vfmov,vldm,vstm,vmalu,vsts,vstux,\
-                         vstox,vext")
+                         vstox,vext,vmsfs,vmiota")
           (const_int 4)
 
         ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
                          vsshift,vnclip")
           (const_int 5)
 
-        (eq_attr "type" "vicmp")
+        (eq_attr "type" "vicmp,vimuladd,viwmuladd")
           (const_int 6)
 
-        (eq_attr "type" "vimuladd,viwmuladd")
-          (const_int 6)]
+        (eq_attr "type" "vmpop,vmffs,vmidx")
+          (const_int 3)]
   (const_int INVALID_ATTRIBUTE)))
 
 ;; The tail policy op value.
 (define_attr "ta" ""
-  (cond [(eq_attr "type" "vlde,vimov,vfmov,vext")
+  (cond [(eq_attr "type" "vlde,vimov,vfmov,vext,vmiota")
           (symbol_ref "riscv_vector::get_ta(operands[5])")
 
         ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
           (symbol_ref "riscv_vector::get_ta(operands[6])")
 
         (eq_attr "type" "vimuladd,viwmuladd")
-          (symbol_ref "riscv_vector::get_ta(operands[7])")]
+          (symbol_ref "riscv_vector::get_ta(operands[7])")
+
+        (eq_attr "type" "vmidx")
+          (symbol_ref "riscv_vector::get_ta(operands[4])")]
        (const_int INVALID_ATTRIBUTE)))
 
 ;; The mask policy op value.
 (define_attr "ma" ""
-  (cond [(eq_attr "type" "vlde,vext")
+  (cond [(eq_attr "type" "vlde,vext,vmiota")
           (symbol_ref "riscv_vector::get_ma(operands[6])")
 
         ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
           (symbol_ref "riscv_vector::get_ma(operands[7])")
 
         (eq_attr "type" "vimuladd,viwmuladd")
-          (symbol_ref "riscv_vector::get_ma(operands[8])")]
+          (symbol_ref "riscv_vector::get_ma(operands[8])")
+
+        (eq_attr "type" "vmsfs,vmidx")
+          (symbol_ref "riscv_vector::get_ma(operands[5])")]
        (const_int INVALID_ATTRIBUTE)))
 
 ;; The avl type value.
           (symbol_ref "INTVAL (operands[5])")
 
         (eq_attr "type" "vimuladd,viwmuladd")
-          (symbol_ref "INTVAL (operands[9])")]
+          (symbol_ref "INTVAL (operands[9])")
+
+        (eq_attr "type" "vmsfs,vmidx")
+          (symbol_ref "INTVAL (operands[6])")
+
+        (eq_attr "type" "vmpop,vmffs")
+          (symbol_ref "INTVAL (operands[4])")]
        (const_int INVALID_ATTRIBUTE)))
 
 ;; -----------------------------------------------------------------
   "@
    vlm.v\t%0,%3
    vsm.v\t%3,%0
-   #
+   vmmv.m\t%0,%3
    vmclr.m\t%0
    vmset.m\t%0"
   "&& register_operand (operands[0], <MODE>mode)
-   && register_operand (operands[3], <MODE>mode)"
+   && register_operand (operands[3], <MODE>mode)
+   && INTVAL (operands[5]) == riscv_vector::VLMAX"
   [(set (match_dup 0) (match_dup 3))]
   ""
-  [(set_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
+  [(set_attr "type" "vldm,vstm,vmalu,vmalu,vmalu")
    (set_attr "mode" "<MODE>")])
 
 ;; Dedicated pattern for vsm.v instruction since we can't reuse pred_mov pattern to include
                reg, CONSTM1_RTX (<VM>mode), undef, operands[3], operands[4],
                operands[5], operands[6], operands[7], operands[8]));
              emit_insn (
-               gen_pred_andn<vm> (operands[0], CONSTM1_RTX (<VM>mode), undef,
+               gen_pred_andnot<vm> (operands[0], CONSTM1_RTX (<VM>mode), undef,
                                   operands[1], reg, operands[6], operands[8]));
            }
          else
 ;; -------------------------------------------------------------------------------
 ;; Includes:
 ;; - 15.1 Vector Mask-Register Logical Instructions
+;; - 15.2 Vector count population in mask vcpop.m
+;; - 15.3 vfirst find-first-set mask bit
+;; - 15.4 vmsbf.m set-before-first mask bit
+;; - 15.5 vmsif.m set-including-first mask bit
+;; - 15.6 vmsof.m set-only-first mask bit
+;; - 15.8 Vector Iota Instruction
+;; - 15.9 Vector Element Index Instruction
 ;; -------------------------------------------------------------------------------
 
 ;; We keep this pattern same as pred_mov so that we can gain more optimizations.
    (set_attr "vl_op_idx" "5")
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[6])"))])
 
-(define_insn "@pred_<optab>n<mode>"
+(define_insn "@pred_<optab>not<mode>"
   [(set (match_operand:VB 0 "register_operand"                   "=vr")
        (if_then_else:VB
          (unspec:VB
            (match_operand:VB 3 "register_operand"               " vr"))
          (match_operand:VB 2 "vector_undef_operand"             " vu")))]
   "TARGET_VECTOR"
-  "vmnot.mm\t%0,%3"
+  "vmnot.m\t%0,%3"
   [(set_attr "type" "vmalu")
    (set_attr "mode" "<MODE>")
    (set_attr "vl_op_idx" "4")
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+
+(define_insn "@pred_popcount<VB:mode><P:mode>"
+  [(set (match_operand:P 0 "register_operand"               "=r")
+       (popcount:P
+         (unspec:VB
+           [(and:VB
+              (match_operand:VB 1 "vector_mask_operand" "vmWc1")
+              (match_operand:VB 2 "register_operand"    "   vr"))
+            (match_operand 3 "vector_length_operand"    "   rK")
+            (match_operand 4 "const_int_operand"        "    i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)))]
+  "TARGET_VECTOR"
+  "vcpop.m\t%0,%2%p1"
+  [(set_attr "type" "vmpop")
+   (set_attr "mode" "<VB:MODE>")])
+
+(define_insn "@pred_ffs<VB:mode><P:mode>"
+  [(set (match_operand:P 0 "register_operand"                 "=r")
+       (plus:P
+         (ffs:P
+           (unspec:VB
+             [(and:VB
+                (match_operand:VB 1 "vector_mask_operand" "vmWc1")
+                (match_operand:VB 2 "register_operand"    "   vr"))
+              (match_operand 3 "vector_length_operand"    "   rK")
+              (match_operand 4 "const_int_operand"        "    i")
+              (reg:SI VL_REGNUM)
+              (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE))
+         (const_int -1)))]
+  "TARGET_VECTOR"
+  "vfirst.m\t%0,%2%p1"
+  [(set_attr "type" "vmffs")
+   (set_attr "mode" "<VB:MODE>")])
+
+(define_insn "@pred_<misc_op><mode>"
+  [(set (match_operand:VB 0 "register_operand"          "=&vr")
+       (if_then_else:VB
+         (unspec:VB
+           [(match_operand:VB 1 "vector_mask_operand" "vmWc1")
+            (match_operand 4 "vector_length_operand"  "   rK")
+            (match_operand 5 "const_int_operand"      "    i")
+            (match_operand 6 "const_int_operand"      "    i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (unspec:VB
+           [(match_operand:VB 3 "register_operand"    "   vr")] VMISC)
+         (match_operand:VB 2 "vector_merge_operand"   "  0vu")))]
+  "TARGET_VECTOR"
+  "vm<misc_op>.m\t%0,%3%p1"
+  [(set_attr "type" "vmsfs")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_iota<mode>"
+  [(set (match_operand:VI 0 "register_operand"            "=&vr")
+       (if_then_else:VI
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+            (match_operand 4 "vector_length_operand"    "   rK")
+            (match_operand 5 "const_int_operand"        "    i")
+            (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
+           [(match_operand:<VM> 3 "register_operand"    "   vr")] UNSPEC_VIOTA)
+         (match_operand:VI 2 "vector_merge_operand"     "  0vu")))]
+  "TARGET_VECTOR"
+  "viota.m\t%0,%3%p1"
+  [(set_attr "type" "vmiota")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_series<mode>"
+  [(set (match_operand:VI 0 "register_operand"           "=vd, vr")
+       (if_then_else:VI
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+            (match_operand 3 "vector_length_operand"    " rK, rK")
+            (match_operand 4 "const_int_operand"        "  i,  i")
+            (match_operand 5 "const_int_operand"        "  i,  i")
+            (match_operand 6 "const_int_operand"        "  i,  i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (vec_series:VI (const_int 0) (const_int 1))
+         (match_operand:VI 2 "vector_merge_operand"     "0vu,0vu")))]
+  "TARGET_VECTOR"
+  "vid.v\t%0%p1"
+  [(set_attr "type" "vmidx")
+   (set_attr "mode" "<MODE>")])
This page took 0.080936 seconds and 5 git commands to generate.