]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Add vsext/vzext C/C++ intrinsic support
authorJu-Zhe Zhong <juzhe.zhong@rivai.ai>
Mon, 6 Feb 2023 05:06:56 +0000 (13:06 +0800)
committerKito Cheng <kito.cheng@sifive.com>
Sun, 12 Feb 2023 03:03:51 +0000 (11:03 +0800)
gcc/ChangeLog:

* config/riscv/iterators.md: Add sign_extend/zero_extend.
* config/riscv/riscv-vector-builtins-bases.cc (class ext): New class.
(BASE): Ditto.
* config/riscv/riscv-vector-builtins-bases.h: Add vsext/vzext support.
* config/riscv/riscv-vector-builtins-functions.def (vsext): New macro
define.
(vzext): Ditto.
* config/riscv/riscv-vector-builtins-shapes.cc (struct alu_def): Adjust
for vsext/vzext support.
* config/riscv/riscv-vector-builtins-types.def (DEF_RVV_WEXTI_OPS): New
macro define.
(DEF_RVV_QEXTI_OPS): Ditto.
(DEF_RVV_OEXTI_OPS): Ditto.
(DEF_RVV_WEXTU_OPS): Ditto.
(DEF_RVV_QEXTU_OPS): Ditto.
(DEF_RVV_OEXTU_OPS): Ditto.
(vint16mf4_t): Ditto.
(vint16mf2_t): Ditto.
(vint16m1_t): Ditto.
(vint16m2_t): Ditto.
(vint16m4_t): Ditto.
(vint16m8_t): Ditto.
(vint32mf2_t): Ditto.
(vint32m1_t): Ditto.
(vint32m2_t): Ditto.
(vint32m4_t): Ditto.
(vint32m8_t): Ditto.
(vint64m1_t): Ditto.
(vint64m2_t): Ditto.
(vint64m4_t): Ditto.
(vint64m8_t): Ditto.
(vuint16mf4_t): Ditto.
(vuint16mf2_t): Ditto.
(vuint16m1_t): Ditto.
(vuint16m2_t): Ditto.
(vuint16m4_t): Ditto.
(vuint16m8_t): Ditto.
(vuint32mf2_t): Ditto.
(vuint32m1_t): Ditto.
(vuint32m2_t): Ditto.
(vuint32m4_t): Ditto.
(vuint32m8_t): Ditto.
(vuint64m1_t): Ditto.
(vuint64m2_t): Ditto.
(vuint64m4_t): Ditto.
(vuint64m8_t): Ditto.
* config/riscv/riscv-vector-builtins.cc (DEF_RVV_WEXTI_OPS): Ditto.
(DEF_RVV_QEXTI_OPS): Ditto.
(DEF_RVV_OEXTI_OPS): Ditto.
(DEF_RVV_WEXTU_OPS): Ditto.
(DEF_RVV_QEXTU_OPS): Ditto.
(DEF_RVV_OEXTU_OPS): Ditto.
(rvv_arg_type_info::get_base_vector_type): Add sign_exted/zero_extend
support.
(rvv_arg_type_info::get_tree_type): Ditto.
* config/riscv/riscv-vector-builtins.h (enum rvv_base_type): Ditto.
* config/riscv/vector-iterators.md (z): New attribute.
* config/riscv/vector.md (@pred_<optab><mode>_vf2): New pattern.
(@pred_<optab><mode>_vf4): Ditto.
(@pred_<optab><mode>_vf8): Ditto.

gcc/config/riscv/iterators.md
gcc/config/riscv/riscv-vector-builtins-bases.cc
gcc/config/riscv/riscv-vector-builtins-bases.h
gcc/config/riscv/riscv-vector-builtins-functions.def
gcc/config/riscv/riscv-vector-builtins-shapes.cc
gcc/config/riscv/riscv-vector-builtins-types.def
gcc/config/riscv/riscv-vector-builtins.cc
gcc/config/riscv/riscv-vector-builtins.h
gcc/config/riscv/vector-iterators.md
gcc/config/riscv/vector.md

index 7e5415cc80b53dc59fd65219960d0c9becde73c3..f95dd405e12715f4bb02d5e7e07b96cd0187a332 100644 (file)
                         (ss_plus "ssadd")
                         (us_plus "usadd")
                         (ss_minus "sssub")
-                        (us_minus "ussub")])
+                        (us_minus "ussub")
+                        (sign_extend "extend")
+                        (zero_extend "zero_extend")])
 
 ;; <or_optab> code attributes
 (define_code_attr or_optab [(ior "ior")
index 7e6ee1d7b53db8af5735d11b7e4da795000a85b8..1a9469a370a9f07142e0ae2dacb20afb23902ee9 100644 (file)
@@ -197,6 +197,27 @@ public:
   }
 };
 
+/* Implements vsext.vf2/vsext.vf4/vsext.vf8/vzext.vf2/vzext.vf4/vzext.vf8.  */
+template<rtx_code CODE>
+class ext : public function_base
+{
+public:
+  rtx expand (function_expander &e) const override
+  {
+    switch (e.op_info->op)
+      {
+      case OP_TYPE_vf2:
+       return e.use_exact_insn (code_for_pred_vf2 (CODE, e.vector_mode ()));
+      case OP_TYPE_vf4:
+       return e.use_exact_insn (code_for_pred_vf4 (CODE, e.vector_mode ()));
+      case OP_TYPE_vf8:
+       return e.use_exact_insn (code_for_pred_vf8 (CODE, 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;
@@ -241,6 +262,8 @@ static CONSTEXPR const binop<UDIV> vdivu_obj;
 static CONSTEXPR const binop<UMOD> vremu_obj;
 static CONSTEXPR const unop<NEG> vneg_obj;
 static CONSTEXPR const unop<NOT> vnot_obj;
+static CONSTEXPR const ext<SIGN_EXTEND> vsext_obj;
+static CONSTEXPR const ext<ZERO_EXTEND> vzext_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;
@@ -295,6 +318,8 @@ BASE (vdivu)
 BASE (vremu)
 BASE (vneg)
 BASE (vnot)
+BASE (vsext)
+BASE (vzext)
 BASE (vsadd)
 BASE (vssub)
 BASE (vsaddu)
index a59fd918af8b4d07230bf6a3973dc25bebd57ecb..71629f36738c543d35a153af5665cf4188a9d145 100644 (file)
@@ -68,6 +68,8 @@ extern const function_base *const vdivu;
 extern const function_base *const vremu;
 extern const function_base *const vneg;
 extern const function_base *const vnot;
+extern const function_base *const vsext;
+extern const function_base *const vzext;
 extern const function_base *const vsadd;
 extern const function_base *const vssub;
 extern const function_base *const vsaddu;
index 74a1864b725692cfd6f968867afe66fcd20ccfa3..42514ed5a37b3845459495c2083185a5813ba52c 100644 (file)
@@ -100,6 +100,12 @@ DEF_RVV_FUNCTION (vdivu, alu, full_preds, u_vvx_ops)
 DEF_RVV_FUNCTION (vremu, alu, full_preds, u_vvx_ops)
 DEF_RVV_FUNCTION (vneg, alu, full_preds, iu_v_ops)
 DEF_RVV_FUNCTION (vnot, alu, full_preds, iu_v_ops)
+DEF_RVV_FUNCTION (vsext, alu, full_preds, i_vf2_ops)
+DEF_RVV_FUNCTION (vsext, alu, full_preds, i_vf4_ops)
+DEF_RVV_FUNCTION (vsext, alu, full_preds, i_vf8_ops)
+DEF_RVV_FUNCTION (vzext, alu, full_preds, u_vf2_ops)
+DEF_RVV_FUNCTION (vzext, alu, full_preds, u_vf4_ops)
+DEF_RVV_FUNCTION (vzext, alu, full_preds, u_vf8_ops)
 /* 12. Vector Fixed-Point Arithmetic Instructions. */
 DEF_RVV_FUNCTION (vsadd, alu, full_preds, i_vvv_ops)
 DEF_RVV_FUNCTION (vssub, alu, full_preds, i_vvv_ops)
index d6dc4c7049ecabaae912aff09cb425e5e0506784..e772a7ca475be2ac63d24f0fb0bb7babda43ce6e 100644 (file)
@@ -192,14 +192,23 @@ struct alu_def : public build_base
                  bool overloaded_p) const override
   {
     b.append_base_name (instance.base_name);
-    /* vop<sew>_v --> vop<sew>_v_<type>.  */
-    if (!overloaded_p)
+
+    /* vop<sew> --> vop<sew>_<op>. According to rvv-intrinsic-doc, _vv/_vx/_v
+       API doesn't have OP suffix in overloaded function name, otherwise, we
+       always append OP suffix in function name. For example, vsext_vf2.  */
+    if (instance.op_info->op == OP_TYPE_vv || instance.op_info->op == OP_TYPE_vx
+       || instance.op_info->op == OP_TYPE_v)
       {
-       /* vop<sew> --> vop<sew>_v.  */
-       b.append_name (operand_suffixes[instance.op_info->op]);
-       /* vop<sew>_v --> vop<sew>_v_<type>.  */
-       b.append_name (type_suffixes[instance.type.index].vector);
+       if (!overloaded_p)
+         b.append_name (operand_suffixes[instance.op_info->op]);
       }
+    else
+      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)
index a95fad031bedc0dee6edd5ac4bbcb27556f734cc..d3129b9f753b8707991e9497115e464075a58fb6 100644 (file)
@@ -42,6 +42,42 @@ along with GCC; see the file COPYING3. If not see
 #define DEF_RVV_B_OPS(TYPE, REQUIRE)
 #endif
 
+/* Use "DEF_RVV_WEXTI_OPS" macro include Double-Widening signed integer which
+   will be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_WEXTI_OPS
+#define DEF_RVV_WEXTI_OPS(TYPE, REQUIRE)
+#endif
+
+/* Use "DEF_RVV_QEXTI_OPS" macro include Quad-Widening signed integer which will
+   be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_QEXTI_OPS
+#define DEF_RVV_QEXTI_OPS(TYPE, REQUIRE)
+#endif
+
+/* Use "DEF_RVV_OEXTI_OPS" macro include Oct-Widening signed integer which will
+   be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_OEXTI_OPS
+#define DEF_RVV_OEXTI_OPS(TYPE, REQUIRE)
+#endif
+
+/* Use "DEF_RVV_WEXTU_OPS" macro include Double-Widening unsigned integer which
+   will be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_WEXTU_OPS
+#define DEF_RVV_WEXTU_OPS(TYPE, REQUIRE)
+#endif
+
+/* Use "DEF_RVV_QEXTU_OPS" macro include Quad-Widening unsigned integer which
+   will be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_QEXTU_OPS
+#define DEF_RVV_QEXTU_OPS(TYPE, REQUIRE)
+#endif
+
+/* Use "DEF_RVV_OEXTU_OPS" macro include Oct-Widening unsigned integer which
+   will be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_OEXTU_OPS
+#define DEF_RVV_OEXTU_OPS(TYPE, REQUIRE)
+#endif
+
 DEF_RVV_I_OPS (vint8mf8_t, RVV_REQUIRE_ZVE64)
 DEF_RVV_I_OPS (vint8mf4_t, 0)
 DEF_RVV_I_OPS (vint8mf2_t, 0)
@@ -106,7 +142,75 @@ DEF_RVV_B_OPS (vbool4_t, 0)
 DEF_RVV_B_OPS (vbool2_t, 0)
 DEF_RVV_B_OPS (vbool1_t, 0)
 
+DEF_RVV_WEXTI_OPS (vint16mf4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTI_OPS (vint16mf2_t, 0)
+DEF_RVV_WEXTI_OPS (vint16m1_t, 0)
+DEF_RVV_WEXTI_OPS (vint16m2_t, 0)
+DEF_RVV_WEXTI_OPS (vint16m4_t, 0)
+DEF_RVV_WEXTI_OPS (vint16m8_t, 0)
+DEF_RVV_WEXTI_OPS (vint32mf2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTI_OPS (vint32m1_t, 0)
+DEF_RVV_WEXTI_OPS (vint32m2_t, 0)
+DEF_RVV_WEXTI_OPS (vint32m4_t, 0)
+DEF_RVV_WEXTI_OPS (vint32m8_t, 0)
+DEF_RVV_WEXTI_OPS (vint64m1_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTI_OPS (vint64m2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTI_OPS (vint64m4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTI_OPS (vint64m8_t, RVV_REQUIRE_ZVE64)
+
+DEF_RVV_QEXTI_OPS (vint32mf2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTI_OPS (vint32m1_t, 0)
+DEF_RVV_QEXTI_OPS (vint32m2_t, 0)
+DEF_RVV_QEXTI_OPS (vint32m4_t, 0)
+DEF_RVV_QEXTI_OPS (vint32m8_t, 0)
+DEF_RVV_QEXTI_OPS (vint64m1_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTI_OPS (vint64m2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTI_OPS (vint64m4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTI_OPS (vint64m8_t, RVV_REQUIRE_ZVE64)
+
+DEF_RVV_OEXTI_OPS (vint64m1_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_OEXTI_OPS (vint64m2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_OEXTI_OPS (vint64m4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_OEXTI_OPS (vint64m8_t, RVV_REQUIRE_ZVE64)
+
+DEF_RVV_WEXTU_OPS (vuint16mf4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTU_OPS (vuint16mf2_t, 0)
+DEF_RVV_WEXTU_OPS (vuint16m1_t, 0)
+DEF_RVV_WEXTU_OPS (vuint16m2_t, 0)
+DEF_RVV_WEXTU_OPS (vuint16m4_t, 0)
+DEF_RVV_WEXTU_OPS (vuint16m8_t, 0)
+DEF_RVV_WEXTU_OPS (vuint32mf2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTU_OPS (vuint32m1_t, 0)
+DEF_RVV_WEXTU_OPS (vuint32m2_t, 0)
+DEF_RVV_WEXTU_OPS (vuint32m4_t, 0)
+DEF_RVV_WEXTU_OPS (vuint32m8_t, 0)
+DEF_RVV_WEXTU_OPS (vuint64m1_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTU_OPS (vuint64m2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTU_OPS (vuint64m4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTU_OPS (vuint64m8_t, RVV_REQUIRE_ZVE64)
+
+DEF_RVV_QEXTU_OPS (vuint32mf2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTU_OPS (vuint32m1_t, 0)
+DEF_RVV_QEXTU_OPS (vuint32m2_t, 0)
+DEF_RVV_QEXTU_OPS (vuint32m4_t, 0)
+DEF_RVV_QEXTU_OPS (vuint32m8_t, 0)
+DEF_RVV_QEXTU_OPS (vuint64m1_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTU_OPS (vuint64m2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTU_OPS (vuint64m4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTU_OPS (vuint64m8_t, RVV_REQUIRE_ZVE64)
+
+DEF_RVV_OEXTU_OPS (vuint64m1_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_OEXTU_OPS (vuint64m2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_OEXTU_OPS (vuint64m4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_OEXTU_OPS (vuint64m8_t, RVV_REQUIRE_ZVE64)
+
 #undef DEF_RVV_I_OPS
 #undef DEF_RVV_U_OPS
 #undef DEF_RVV_F_OPS
 #undef DEF_RVV_B_OPS
+#undef DEF_RVV_WEXTI_OPS
+#undef DEF_RVV_QEXTI_OPS
+#undef DEF_RVV_OEXTI_OPS
+#undef DEF_RVV_WEXTU_OPS
+#undef DEF_RVV_QEXTU_OPS
+#undef DEF_RVV_OEXTU_OPS
index 95a949aab7c6f6a97464c42c19834a7f5ff87271..c79628e4a3b4b552c1130011c10cb3f48a657ea8 100644 (file)
@@ -160,6 +160,48 @@ static const rvv_type_info b_ops[] = {
 #include "riscv-vector-builtins-types.def"
   {NUM_VECTOR_TYPES, 0}};
 
+/* A list of Double-Widening signed integer will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info wexti_ops[] = {
+#define DEF_RVV_WEXTI_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
+/* A list of Quad-Widening signed integer will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info qexti_ops[] = {
+#define DEF_RVV_QEXTI_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
+/* A list of Oct-Widening signed integer will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info oexti_ops[] = {
+#define DEF_RVV_OEXTI_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
+/* A list of Double-Widening unsigned integer will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info wextu_ops[] = {
+#define DEF_RVV_WEXTU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
+/* A list of Quad-Widening unsigned integer will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info qextu_ops[] = {
+#define DEF_RVV_QEXTU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
+/* A list of Oct-Widening unsigned integer will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info oextu_ops[] = {
+#define DEF_RVV_OEXTU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
 static CONSTEXPR const rvv_arg_type_info rvv_arg_type_info_end
   = rvv_arg_type_info (NUM_BASE_TYPES);
 
@@ -269,6 +311,18 @@ static CONSTEXPR const rvv_arg_type_info vector_size_args[]
   = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_size),
      rvv_arg_type_info_end};
 
+/* A list of args for vector_type func (double demote type) function.  */
+static CONSTEXPR const rvv_arg_type_info vf2_args[]
+  = {rvv_arg_type_info (RVV_BASE_double_trunc_vector), rvv_arg_type_info_end};
+
+/* A list of args for vector_type func (quad demote type) function.  */
+static CONSTEXPR const rvv_arg_type_info vf4_args[]
+  = {rvv_arg_type_info (RVV_BASE_quad_trunc_vector), rvv_arg_type_info_end};
+
+/* A list of args for vector_type func (oct demote type) function.  */
+static CONSTEXPR const rvv_arg_type_info vf8_args[]
+  = {rvv_arg_type_info (RVV_BASE_oct_trunc_vector), rvv_arg_type_info_end};
+
 /* A list of none preds that will be registered for intrinsic functions.  */
 static CONSTEXPR const predication_type_index none_preds[]
   = {PRED_TYPE_none, NUM_PRED_TYPES};
@@ -481,6 +535,54 @@ static CONSTEXPR const rvv_op_info iu_v_ops
      rvv_arg_type_info (RVV_BASE_vector), /* Return type */
      v_args /* Args */};
 
+/* A static operand information for vector_type func (double demote type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info i_vf2_ops
+  = {wexti_ops,                                  /* Types */
+     OP_TYPE_vf2,                        /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vf2_args /* Args */};
+
+/* A static operand information for vector_type func (quad demote type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info i_vf4_ops
+  = {qexti_ops,                                  /* Types */
+     OP_TYPE_vf4,                        /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vf4_args /* Args */};
+
+/* A static operand information for vector_type func (oct demote type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info i_vf8_ops
+  = {oexti_ops,                                  /* Types */
+     OP_TYPE_vf8,                        /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vf8_args /* Args */};
+
+/* A static operand information for vector_type func (double demote type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_vf2_ops
+  = {wextu_ops,                                  /* Types */
+     OP_TYPE_vf2,                        /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vf2_args /* Args */};
+
+/* A static operand information for vector_type func (quad demote type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_vf4_ops
+  = {qextu_ops,                                  /* Types */
+     OP_TYPE_vf4,                        /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vf4_args /* Args */};
+
+/* A static operand information for vector_type func (oct demote type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_vf8_ops
+  = {oextu_ops,                                  /* Types */
+     OP_TYPE_vf8,                        /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vf8_args /* Args */};
+
 /* A list of all RVV intrinsic functions.  */
 static function_group_info function_groups[] = {
 #define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO)                         \
@@ -763,7 +865,7 @@ rvv_arg_type_info::get_base_vector_type (tree type) const
   if (!type)
     return NUM_VECTOR_TYPES;
   poly_int64 nunits = GET_MODE_NUNITS (TYPE_MODE (type));
-  machine_mode inner_mode;
+  machine_mode inner_mode = GET_MODE_INNER (TYPE_MODE (type));
   bool unsigned_p = TYPE_UNSIGNED (type);
   switch (base_type)
     {
@@ -787,6 +889,30 @@ rvv_arg_type_info::get_base_vector_type (tree type) const
       inner_mode = GET_MODE_INNER (TYPE_MODE (type));
       unsigned_p = true;
       break;
+    case RVV_BASE_double_trunc_vector:
+      if (inner_mode == DImode)
+       inner_mode = SImode;
+      else if (inner_mode == SImode)
+       inner_mode = HImode;
+      else if (inner_mode == HImode)
+       inner_mode = QImode;
+      else
+       gcc_unreachable ();
+      break;
+    case RVV_BASE_quad_trunc_vector:
+      if (inner_mode == DImode)
+       inner_mode = HImode;
+      else if (inner_mode == SImode)
+       inner_mode = QImode;
+      else
+       gcc_unreachable ();
+      break;
+    case RVV_BASE_oct_trunc_vector:
+      if (inner_mode == DImode)
+       inner_mode = QImode;
+      else
+       gcc_unreachable ();
+      break;
     default:
       return NUM_VECTOR_TYPES;
     }
@@ -851,6 +977,9 @@ rvv_arg_type_info::get_tree_type (vector_type_index type_idx) const
     case RVV_BASE_uint32_index:
     case RVV_BASE_uint64_index:
     case RVV_BASE_shift_vector:
+    case RVV_BASE_double_trunc_vector:
+    case RVV_BASE_quad_trunc_vector:
+    case RVV_BASE_oct_trunc_vector:
       if (get_base_vector_type (builtin_types[type_idx].vector)
          != NUM_VECTOR_TYPES)
        return builtin_types[get_base_vector_type (
index c20d8f8835c8c29262f89d2308793d5b14735a94..f14b6a55ec23cc5e1fd8887335c06c616629f517 100644 (file)
@@ -152,6 +152,9 @@ enum rvv_base_type
   RVV_BASE_uint32_index,
   RVV_BASE_uint64_index,
   RVV_BASE_shift_vector,
+  RVV_BASE_double_trunc_vector,
+  RVV_BASE_quad_trunc_vector,
+  RVV_BASE_oct_trunc_vector,
   NUM_BASE_TYPES
 };
 
index 2460ed670c0070ad9856b4bf43e7f19e4b593ebb..6528e5711a46e857250b654de40e54a8dcddb274 100644 (file)
   (VNx64BI "TARGET_MIN_VLEN > 32")
 ])
 
+(define_mode_iterator VWEXTI [
+  VNx1HI VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32")
+  VNx1SI VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32")
+  (VNx1DI "TARGET_MIN_VLEN > 32") (VNx2DI "TARGET_MIN_VLEN > 32")
+  (VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32")
+])
+
+(define_mode_iterator VQEXTI [
+  VNx1SI VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32")
+  (VNx1DI "TARGET_MIN_VLEN > 32") (VNx2DI "TARGET_MIN_VLEN > 32")
+  (VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32")
+])
+
+(define_mode_iterator VOEXTI [
+  (VNx1DI "TARGET_MIN_VLEN > 32") (VNx2DI "TARGET_MIN_VLEN > 32")
+  (VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32")
+])
+
 (define_mode_attr VM [
   (VNx1QI "VNx1BI") (VNx2QI "VNx2BI") (VNx4QI "VNx4BI") (VNx8QI "VNx8BI") (VNx16QI "VNx16BI") (VNx32QI "VNx32BI") (VNx64QI "VNx64BI")
   (VNx1HI "VNx1BI") (VNx2HI "VNx2BI") (VNx4HI "VNx4BI") (VNx8HI "VNx8BI") (VNx16HI "VNx16BI") (VNx32HI "VNx32BI")
   (VNx1DF "64") (VNx2DF "64") (VNx4DF "64") (VNx8DF "64")
 ])
 
+(define_mode_attr V_DOUBLE_TRUNC [
+  (VNx1HI "VNx1QI") (VNx2HI "VNx2QI")  (VNx4HI "VNx4QI")  (VNx8HI "VNx8QI")  
+  (VNx16HI "VNx16QI") (VNx32HI "VNx32QI")
+  (VNx1SI "VNx1HI") (VNx2SI "VNx2HI") (VNx4SI "VNx4HI") (VNx8SI "VNx8HI") 
+  (VNx16SI "VNx16HI")
+  (VNx1DI "VNx1SI") (VNx2DI "VNx2SI") (VNx4DI "VNx4SI") (VNx8DI "VNx8SI")
+])
+
+(define_mode_attr V_QUAD_TRUNC [
+  (VNx1SI "VNx1QI") (VNx2SI "VNx2QI") (VNx4SI "VNx4QI") (VNx8SI "VNx8QI") 
+  (VNx16SI "VNx16QI")
+  (VNx1DI "VNx1HI") (VNx2DI "VNx2HI")
+  (VNx4DI "VNx4HI") (VNx8DI "VNx8HI")
+])
+
+(define_mode_attr V_OCT_TRUNC [
+  (VNx1DI "VNx1QI") (VNx2DI "VNx2QI") (VNx4DI "VNx4QI") (VNx8DI "VNx8QI")
+])
+
 (define_int_iterator ORDER [UNSPEC_ORDERED UNSPEC_UNORDERED])
 
 (define_int_attr order [
                              (umin "%3,%4")
                              (umax "%3,%4")
                              (mult "%3,%4")])
+
+(define_code_attr sz [(sign_extend "s") (zero_extend "z")])
index 44584e171057b65696027649e5cbea94a7d66536..8bafbdc870482856c77e3889a39f3cfb631ff913 100644 (file)
 ;; 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")
+                         vialu,vshift,vicmp,vimul,vidiv,vsalu,vext")
           (const_int INVALID_ATTRIBUTE)
         (eq_attr "mode" "VNx1QI,VNx1BI")
           (symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)")
 ;; The index of operand[] to get the merge op.
 (define_attr "merge_op_idx" ""
        (cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu,vldux,vldox,\
-                               vialu,vshift,vicmp,vimul,vidiv,vsalu")
+                               vialu,vshift,vicmp,vimul,vidiv,vsalu,vext")
         (const_int 2)]
        (const_int INVALID_ATTRIBUTE)))
 
 ;; 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")
+  (cond [(eq_attr "type" "vlde,vste,vimov,vfmov,vldm,vstm,vmalu,vsts,vstux,\
+                         vstox,vext")
           (const_int 4)
 
         ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
 
 ;; The tail policy op value.
 (define_attr "ta" ""
-  (cond [(eq_attr "type" "vlde,vimov,vfmov")
+  (cond [(eq_attr "type" "vlde,vimov,vfmov,vext")
           (symbol_ref "riscv_vector::get_ta(operands[5])")
 
         ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
 
 ;; The mask policy op value.
 (define_attr "ma" ""
-  (cond [(eq_attr "type" "vlde")
+  (cond [(eq_attr "type" "vlde,vext")
           (symbol_ref "riscv_vector::get_ma(operands[6])")
 
         ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
 
 ;; The avl type value.
 (define_attr "avl_type" ""
-  (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov")
+  (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov,vext")
           (symbol_ref "INTVAL (operands[7])")
         (eq_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
           (symbol_ref "INTVAL (operands[5])")
    (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])"))
    (set (attr "ma") (symbol_ref "riscv_vector::get_ta(operands[6])"))
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+
+;; -------------------------------------------------------------------------------
+;; ---- Predicated integer widening operations
+;; -------------------------------------------------------------------------------
+;; Includes:
+;; - 11.3 Vector Integer Extension
+;; -------------------------------------------------------------------------------
+
+;; Vector Double-Widening Sign-extend and Zero-extend.
+(define_insn "@pred_<optab><mode>_vf2"
+  [(set (match_operand:VWEXTI 0 "register_operand"            "=&vr")
+       (if_then_else:VWEXTI
+         (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)
+         (any_extend:VWEXTI
+           (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "   vr"))
+         (match_operand:VWEXTI 2 "vector_merge_operand"         "  0vu")))]
+  "TARGET_VECTOR"
+  "v<sz>ext.vf2\t%0,%3%p1"
+  [(set_attr "type" "vext")
+   (set_attr "mode" "<MODE>")])
+
+;; Vector Quad-Widening Sign-extend and Zero-extend.
+(define_insn "@pred_<optab><mode>_vf4"
+  [(set (match_operand:VQEXTI 0 "register_operand"          "=&vr")
+       (if_then_else:VQEXTI
+         (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)
+         (any_extend:VQEXTI
+           (match_operand:<V_QUAD_TRUNC> 3 "register_operand" "   vr"))
+         (match_operand:VQEXTI 2 "vector_merge_operand"       "  0vu")))]
+  "TARGET_VECTOR"
+  "v<sz>ext.vf4\t%0,%3%p1"
+  [(set_attr "type" "vext")
+   (set_attr "mode" "<MODE>")])
+
+;; Vector Oct-Widening Sign-extend and Zero-extend.
+(define_insn "@pred_<optab><mode>_vf8"
+  [(set (match_operand:VOEXTI 0 "register_operand"         "=&vr")
+       (if_then_else:VOEXTI
+         (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)
+         (any_extend:VOEXTI
+           (match_operand:<V_OCT_TRUNC> 3 "register_operand" "   vr"))
+         (match_operand:VOEXTI 2 "vector_merge_operand"      "  0vu")))]
+  "TARGET_VECTOR"
+  "v<sz>ext.vf8\t%0,%3%p1"
+  [(set_attr "type" "vext")
+   (set_attr "mode" "<MODE>")])