https://gcc.gnu.org/g:356bfe8ca123954e524a9d09dd8bba5ae8474a2d

commit r15-5793-g356bfe8ca123954e524a9d09dd8bba5ae8474a2d
Author: yulong <shiyul...@iscas.ac.cn>
Date:   Thu Nov 28 10:36:04 2024 +0800

    RISC-V: Add intrinsics support for SiFive Xsfvqmaccqoq/dod extensions.
    
    This commit adds intrinsics support for Xsfvqmaccqoq/dod.
    
    Co-Authored by: Jiawei Chen <jia...@iscas.ac.cn>
    Co-Authored by: Shihua Liao <shi...@iscas.ac.cn>
    Co-Authored by: Yixuan Chen <chenyix...@iscas.ac.cn>
    
    gcc/ChangeLog:
    
            * config.gcc: Add new SiFive *.o files.
            * config/riscv/generic-vector-ooo.md: New reservation.
            * config/riscv/genrvv-type-indexer.cc (main): New type.
            * config/riscv/riscv-vector-builtins-shapes.cc (struct 
sf_vqmacc_def): New function.
            (SHAPE): Ditto.
            * config/riscv/riscv-vector-builtins-shapes.h: Ditto.
            * config/riscv/riscv-vector-builtins-types.def (DEF_RVV_QMACC_OPS): 
New macros type.
            (vint32m1_t): Ditto.
            (vint32m2_t): Ditto.
            (vint32m4_t): Ditto.
            (vint32m8_t): Ditto.
            * config/riscv/riscv-vector-builtins.cc (DEF_RVV_QMACC_OPS): New 
builtins def.
            (DEF_RVV_TYPE_INDEX): Ditto.
            (DEF_RVV_FUNCTION): Ditto.
            * config/riscv/riscv-vector-builtins.def (DEF_RVV_TYPE_INDEX): New 
types def.
            (4x8x4): New op type.
            (2x8x2): Ditto.
            (quad_emul_vector): New base type.
            (quad_emul_signed_vector): Ditto.
            (quad_emul_unsigned_vector): Ditto.
            (quad_fixed_vector): Ditto.
            (quad_fixed_signed_vector): Ditto.
            (quad_fixed_unsigned_vector): Ditto.
            (quad_lmul1_vector): Ditto.
            (quad_lmul1_signed_vector): Ditto.
            (quad_lmul1_unsigned_vector): Ditto.
            * config/riscv/riscv-vector-builtins.h (enum required_ext): New 
extensions.
            (required_ext_to_isa_name): Ditto.
            (required_extensions_specified): Ditto.
            (struct function_group_info): Ditto.
            * config/riscv/riscv.md: New attr.
            * config/riscv/t-riscv: Add include for SiFive files.
            * config/riscv/vector-iterators.md: New iterator.
            * config/riscv/vector.md: New include for SiFive file.
            * config/riscv/sifive-vector-builtins-bases.cc: New file.
            * config/riscv/sifive-vector-builtins-bases.h: New file.
            * config/riscv/sifive-vector-builtins-functions.def: New file.
            * config/riscv/sifive-vector.md: New file.

Diff:
---
 gcc/config.gcc                                     |   2 +-
 gcc/config/riscv/generic-vector-ooo.md             |   2 +-
 gcc/config/riscv/genrvv-type-indexer.cc            |  47 ++++++
 gcc/config/riscv/riscv-vector-builtins-shapes.cc   |  30 ++++
 gcc/config/riscv/riscv-vector-builtins-shapes.h    |   2 +
 gcc/config/riscv/riscv-vector-builtins-types.def   |  12 ++
 gcc/config/riscv/riscv-vector-builtins.cc          | 151 +++++++++++++++++--
 gcc/config/riscv/riscv-vector-builtins.def         |  26 +++-
 gcc/config/riscv/riscv-vector-builtins.h           |  14 ++
 gcc/config/riscv/riscv.md                          |   4 +-
 gcc/config/riscv/sifive-vector-builtins-bases.cc   | 164 +++++++++++++++++++++
 gcc/config/riscv/sifive-vector-builtins-bases.h    |  35 +++++
 .../riscv/sifive-vector-builtins-functions.def     |  54 +++++++
 gcc/config/riscv/sifive-vector.md                  | 164 +++++++++++++++++++++
 gcc/config/riscv/t-riscv                           |  20 +++
 gcc/config/riscv/vector-iterators.md               |  32 ++++
 gcc/config/riscv/vector.md                         |   1 +
 17 files changed, 741 insertions(+), 19 deletions(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 12018d2193ca..afa78453197a 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -552,7 +552,7 @@ riscv*)
        cpu_type=riscv
        extra_objs="riscv-builtins.o riscv-c.o riscv-sr.o 
riscv-shorten-memrefs.o riscv-selftests.o riscv-string.o"
        extra_objs="${extra_objs} riscv-v.o riscv-vsetvl.o riscv-vector-costs.o 
riscv-avlprop.o"
-       extra_objs="${extra_objs} riscv-vector-builtins.o 
riscv-vector-builtins-shapes.o riscv-vector-builtins-bases.o"
+       extra_objs="${extra_objs} riscv-vector-builtins.o 
riscv-vector-builtins-shapes.o riscv-vector-builtins-bases.o 
sifive-vector-builtins-bases.o"
        extra_objs="${extra_objs} thead.o riscv-target-attr.o"
        d_target_objs="riscv-d.o"
        extra_headers="riscv_vector.h riscv_crypto.h riscv_bitmanip.h 
riscv_th_vector.h riscv_cmo.h"
diff --git a/gcc/config/riscv/generic-vector-ooo.md 
b/gcc/config/riscv/generic-vector-ooo.md
index efe6bc41e864..132ab0398228 100644
--- a/gcc/config/riscv/generic-vector-ooo.md
+++ b/gcc/config/riscv/generic-vector-ooo.md
@@ -69,7 +69,7 @@
 
 ;; Vector float multiplication and FMA.
 (define_insn_reservation "vec_fmul" 6
-  (eq_attr "type" "vfmul,vfwmul,vfmuladd,vfwmuladd,vfwmaccbf16")
+  (eq_attr "type" "vfmul,vfwmul,vfmuladd,vfwmuladd,vfwmaccbf16,sf_vqmacc")
   "vxu_ooo_issue,vxu_ooo_alu")
 
 ;; Vector crypto, assumed to be a generic operation for now.
diff --git a/gcc/config/riscv/genrvv-type-indexer.cc 
b/gcc/config/riscv/genrvv-type-indexer.cc
index 8626ddeaaa8b..8822e101c530 100644
--- a/gcc/config/riscv/genrvv-type-indexer.cc
+++ b/gcc/config/riscv/genrvv-type-indexer.cc
@@ -255,6 +255,12 @@ main (int argc, const char **argv)
       fprintf (fp, "  /*SHIFT*/ INVALID,\n");
       fprintf (fp, "  /*DOUBLE_TRUNC*/ INVALID,\n");
       fprintf (fp, "  /*QUAD_TRUNC*/ INVALID,\n");
+      fprintf (fp, "  /*QUAD_EMUL*/ INVALID,\n");
+      fprintf (fp, "  /*QUAD_EMUL_SIGNED*/ INVALID,\n");
+      fprintf (fp, "  /*QUAD_EMUL_UNSIGNED*/ INVALID,\n");
+      fprintf (fp, "  /*QUAD_FIX*/ INVALID,\n");
+      fprintf (fp, "  /*QUAD_FIX_SIGNED*/ INVALID,\n");
+      fprintf (fp, "  /*QUAD_FIX_UNSIGNED*/ INVALID,\n");
       fprintf (fp, "  /*OCT_TRUNC*/ INVALID,\n");
       fprintf (fp, "  /*DOUBLE_TRUNC_SCALAR*/ INVALID,\n");
       fprintf (fp, "  /*DOUBLE_TRUNC_SIGNED*/ INVALID,\n");
@@ -266,6 +272,9 @@ main (int argc, const char **argv)
       fprintf (fp, "  /*FLOAT*/ INVALID,\n");
       fprintf (fp, "  /*LMUL1*/ INVALID,\n");
       fprintf (fp, "  /*WLMUL1*/ INVALID,\n");
+      fprintf (fp, "  /*QLMUL1*/ INVALID,\n");
+      fprintf (fp, "  /*QLMUL1_SIGNED*/ INVALID,\n");
+      fprintf (fp, "  /*QLMUL1_UNSIGNED*/ INVALID,\n");
       for (unsigned eew : {8, 16, 32, 64})
        fprintf (fp, "  /*EEW%d_INTERPRET*/ INVALID,\n", eew);
 
@@ -322,6 +331,18 @@ main (int argc, const char **argv)
                     same_ratio_eew_type (sew, lmul_log2, sew / 4, unsigned_p,
                                          false)
                       .c_str ());
+           fprintf (fp, "  /*QUAD_EMUL*/ %s,\n",
+                    inttype (8, lmul_log2 - 1, unsigned_p).c_str ());
+           fprintf (fp, "  /*QUAD_EMUL_SIGNED*/ %s,\n",
+                    inttype (8, lmul_log2 - 1, false).c_str ());
+           fprintf (fp, "  /*QUAD_EMUL_UNSIGNED*/ %s,\n",
+                    inttype (8, lmul_log2 - 1, true).c_str ());
+           fprintf (fp, "  /*QUAD_FIX*/ %s,\n",
+                    inttype (8, lmul_log2, unsigned_p).c_str ());
+           fprintf (fp, "  /*QUAD_FIX_SIGNED*/ %s,\n",
+                    inttype (8, lmul_log2, false).c_str ());
+           fprintf (fp, "  /*QUAD_FIX_UNSIGNED*/ %s,\n",
+                    inttype (8, lmul_log2, true).c_str ());
            fprintf (fp, "  /*OCT_TRUNC*/ %s,\n",
                     same_ratio_eew_type (sew, lmul_log2, sew / 8, unsigned_p,
                                          false)
@@ -352,6 +373,12 @@ main (int argc, const char **argv)
                     inttype (sew, /*lmul_log2*/ 0, unsigned_p).c_str ());
            fprintf (fp, "  /*WLMUL1*/ %s,\n",
                     inttype (sew * 2, /*lmul_log2*/ 0, unsigned_p).c_str ());
+           fprintf (fp, "  /*QLMUL1*/ %s,\n",
+                    inttype (8, /*lmul_log2*/ 0, unsigned_p).c_str ());
+           fprintf (fp, "  /*QLMUL1_SIGNED*/ %s,\n",
+                    inttype (8, /*lmul_log2*/ 0, false).c_str ());
+           fprintf (fp, "  /*QLMUL1_UNSIGNED*/ %s,\n",
+                    inttype (8, /*lmul_log2*/ 0, true).c_str ());
            for (unsigned eew : {8, 16, 32, 64})
              {
                if (eew == sew)
@@ -413,6 +440,12 @@ main (int argc, const char **argv)
        fprintf (fp, "  /*DOUBLE_TRUNC*/ %s,\n",
                 same_ratio_eew_type (16, lmul_log2, 8, false, true).c_str ());
        fprintf (fp, "  /*QUAD_TRUNC*/ INVALID,\n");
+       fprintf (fp, "  /*QUAD_EMUL*/ INVALID,\n");
+       fprintf (fp, "  /*QUAD_EMUL_SIGNED*/ INVALID,\n");
+       fprintf (fp, "  /*QUAD_EMUL_UNSIGNED*/ INVALID,\n");
+       fprintf (fp, "  /*QUAD_FIX*/ INVALID,\n");
+       fprintf (fp, "  /*QUAD_FIX_SIGNED*/ INVALID,\n");
+       fprintf (fp, "  /*QUAD_FIX_UNSIGNED*/ INVALID,\n");
        fprintf (fp, "  /*OCT_TRUNC*/ INVALID,\n");
        fprintf (fp, "  /*DOUBLE_TRUNC_SCALAR*/ %s,\n",
                 same_ratio_eew_type (16, lmul_log2, 8, false, true).c_str ());
@@ -430,6 +463,10 @@ main (int argc, const char **argv)
                 bfloat16_type (/*lmul_log2*/ 0).c_str ());
        fprintf (fp, "  /*WLMUL1*/ %s,\n",
                 bfloat16_wide_type (/*lmul_log2*/ 0).c_str ());
+       fprintf (fp, "  /*QLMUL1*/ %s,\n",
+                bfloat16_wide_type (/*lmul_log2*/ 0).c_str ());
+       fprintf (fp, "  /*QLMUL1_SIGNED*/ INVALID,\n");
+       fprintf (fp, "  /*QLMUL1_UNSIGNED*/ INVALID,\n");
        for (unsigned eew : {8, 16, 32, 64})
          fprintf (fp, "  /*EEW%d_INTERPRET*/ INVALID,\n", eew);
 
@@ -478,6 +515,12 @@ main (int argc, const char **argv)
                   same_ratio_eew_type (sew, lmul_log2, sew / 2, false, true)
                     .c_str ());
          fprintf (fp, "  /*QUAD_TRUNC*/ INVALID,\n");
+         fprintf (fp, "  /*QUAD_EMUL*/ INVALID,\n");
+         fprintf (fp, "  /*QUAD_EMUL_SIGNED*/ INVALID,\n");
+         fprintf (fp, "  /*QUAD_EMUL_UNSIGNED*/ INVALID,\n");
+         fprintf (fp, "  /*QUAD_FIX*/ INVALID,\n");
+         fprintf (fp, "  /*QUAD_FIX_SIGNED*/ INVALID,\n");
+         fprintf (fp, "  /*QUAD_FIX_UNSIGNED*/ INVALID,\n");
          fprintf (fp, "  /*OCT_TRUNC*/ INVALID,\n");
          fprintf (fp, "  /*DOUBLE_TRUNC_SCALAR*/ %s,\n",
                   same_ratio_eew_type (sew, lmul_log2, sew / 2, false, true)
@@ -501,6 +544,10 @@ main (int argc, const char **argv)
                   floattype (sew, /*lmul_log2*/ 0).c_str ());
          fprintf (fp, "  /*WLMUL1*/ %s,\n",
                   floattype (sew * 2, /*lmul_log2*/ 0).c_str ());
+         fprintf (fp, "  /*QLMUL1*/ %s,\n",
+                  floattype (sew / 4, /*lmul_log2*/ 0).c_str ());
+         fprintf (fp, "  /*QLMUL1_SIGNED*/ INVALID,\n");
+         fprintf (fp, "  /*QLMUL1_UNSIGNED*/ INVALID,\n");
          for (unsigned eew : {8, 16, 32, 64})
            fprintf (fp, "  /*EEW%d_INTERPRET*/ INVALID,\n", eew);
 
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc 
b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
index 22cbbc215954..3d41d04965b4 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
@@ -1287,6 +1287,35 @@ struct crypto_vv_no_op_type_def : public build_base
   }
 };
 
+/* sf_vqmacc_def class.  */
+struct sf_vqmacc_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);
+
+    /* vop --> vop_v.  */
+    b.append_name (operand_suffixes[instance.op_info->op]);
+
+    /* Return nullptr if it can not be overloaded.  */
+    if (overloaded_p && !instance.base->can_be_overloaded_p (instance.pred))
+      return b.finish_name ();
+
+    if (!overloaded_p)
+      {
+       /* vop_v --> vop_v_<type>.  */
+       b.append_name (type_suffixes[instance.type.index].vector);
+      }
+
+    /* According to SIFIVE vector-intrinsic-doc, it adds "_tu" suffix
+       for vop_m C++ overloaded API.*/
+    b.append_name (predication_suffixes[instance.pred]);
+
+    return b.finish_name ();
+  }
+};
+
 SHAPE(vsetvl, vsetvl)
 SHAPE(vsetvl, vsetvlmax)
 SHAPE(loadstore, loadstore)
@@ -1321,4 +1350,5 @@ SHAPE(seg_fault_load, seg_fault_load)
 SHAPE(crypto_vv, crypto_vv)
 SHAPE(crypto_vi, crypto_vi)
 SHAPE(crypto_vv_no_op_type, crypto_vv_no_op_type)
+SHAPE (sf_vqmacc, sf_vqmacc)
 } // 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 3de837c158e0..a06960de71e2 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.h
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h
@@ -59,6 +59,8 @@ extern const function_shape *const seg_fault_load;
 extern const function_shape *const crypto_vv;
 extern const function_shape *const crypto_vi;
 extern const function_shape *const crypto_vv_no_op_type;
+/* Sifive vendor extension.  */
+extern const function_shape *const sf_vqmacc;
 }
 
 } // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins-types.def 
b/gcc/config/riscv/riscv-vector-builtins-types.def
index e85ca27bcf55..96412bfd1a56 100644
--- a/gcc/config/riscv/riscv-vector-builtins-types.def
+++ b/gcc/config/riscv/riscv-vector-builtins-types.def
@@ -357,6 +357,12 @@ along with GCC; see the file COPYING3. If not see
 #define DEF_RVV_CRYPTO_SEW64_OPS(TYPE, REQUIRE)
 #endif
 
+/* Use "DEF_RVV_QMACC_OPS" macro include signed integer which will
+   be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_QMACC_OPS
+#define DEF_RVV_QMACC_OPS(TYPE, REQUIRE)
+#endif
+
 DEF_RVV_I_OPS (vint8mf8_t, RVV_REQUIRE_MIN_VLEN_64)
 DEF_RVV_I_OPS (vint8mf4_t, 0)
 DEF_RVV_I_OPS (vint8mf2_t, 0)
@@ -1440,6 +1446,11 @@ DEF_RVV_CRYPTO_SEW64_OPS (vuint64m2_t, 
RVV_REQUIRE_ELEN_64)
 DEF_RVV_CRYPTO_SEW64_OPS (vuint64m4_t, RVV_REQUIRE_ELEN_64)
 DEF_RVV_CRYPTO_SEW64_OPS (vuint64m8_t, RVV_REQUIRE_ELEN_64)
 
+DEF_RVV_QMACC_OPS (vint32m1_t, 0)
+DEF_RVV_QMACC_OPS (vint32m2_t, 0)
+DEF_RVV_QMACC_OPS (vint32m4_t, 0)
+DEF_RVV_QMACC_OPS (vint32m8_t, 0)
+
 #undef DEF_RVV_I_OPS
 #undef DEF_RVV_U_OPS
 #undef DEF_RVV_F_OPS
@@ -1494,3 +1505,4 @@ DEF_RVV_CRYPTO_SEW64_OPS (vuint64m8_t, 
RVV_REQUIRE_ELEN_64)
 #undef DEF_RVV_CRYPTO_SEW32_OPS
 #undef DEF_RVV_CRYPTO_SEW64_OPS
 #undef DEF_RVV_F32_OPS
+#undef DEF_RVV_QMACC_OPS
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc 
b/gcc/config/riscv/riscv-vector-builtins.cc
index 41730c483ee1..f49e3311d2fc 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -51,6 +51,7 @@
 #include "riscv-vector-builtins.h"
 #include "riscv-vector-builtins-shapes.h"
 #include "riscv-vector-builtins-bases.h"
+#include "sifive-vector-builtins-bases.h"
 
 using namespace riscv_vector;
 
@@ -543,6 +544,13 @@ static const rvv_type_info crypto_sew64_ops[] = {
 #include "riscv-vector-builtins-types.def"
   {NUM_VECTOR_TYPES, 0}};
 
+/* A list of signed integer will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info qmacc_ops[] = {
+#define DEF_RVV_QMACC_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);
 
@@ -854,6 +862,54 @@ static CONSTEXPR const rvv_arg_type_info us_wwxv_args[]
      rvv_arg_type_info (RVV_BASE_double_trunc_vector),
      rvv_arg_type_info_end};
 
+/* A static operand information for vector_type func (vector_type, quad lmul1
+ * type, quad half lmul type) function registration. */
+static CONSTEXPR const rvv_arg_type_info qqvv_args[]
+  = {rvv_arg_type_info (RVV_BASE_vector),
+     rvv_arg_type_info (RVV_BASE_quad_lmul1_vector),
+     rvv_arg_type_info (RVV_BASE_quad_emul_vector), rvv_arg_type_info_end};
+
+static CONSTEXPR const rvv_arg_type_info uqqvv_args[]
+  = {rvv_arg_type_info (RVV_BASE_vector),
+     rvv_arg_type_info (RVV_BASE_quad_lmul1_unsigned_vector),
+     rvv_arg_type_info (RVV_BASE_quad_emul_unsigned_vector),
+     rvv_arg_type_info_end};
+
+static CONSTEXPR const rvv_arg_type_info su_qqvv_args[]
+  = {rvv_arg_type_info (RVV_BASE_vector),
+     rvv_arg_type_info (RVV_BASE_quad_lmul1_vector),
+     rvv_arg_type_info (RVV_BASE_quad_emul_unsigned_vector),
+     rvv_arg_type_info_end};
+
+static CONSTEXPR const rvv_arg_type_info us_qqvv_args[]
+  = {rvv_arg_type_info (RVV_BASE_vector),
+     rvv_arg_type_info (RVV_BASE_quad_lmul1_unsigned_vector),
+     rvv_arg_type_info (RVV_BASE_quad_emul_vector), rvv_arg_type_info_end};
+
+/* A static operand information for vector_type func (vector_type, quad lmul1
+ * type, quad emul type) function registration. */
+static CONSTEXPR const rvv_arg_type_info qdvv_args[]
+  = {rvv_arg_type_info (RVV_BASE_vector),
+     rvv_arg_type_info (RVV_BASE_quad_lmul1_vector),
+     rvv_arg_type_info (RVV_BASE_quad_fixed_vector), rvv_arg_type_info_end};
+
+static CONSTEXPR const rvv_arg_type_info uqdvv_args[]
+  = {rvv_arg_type_info (RVV_BASE_vector),
+     rvv_arg_type_info (RVV_BASE_quad_lmul1_unsigned_vector),
+     rvv_arg_type_info (RVV_BASE_quad_fixed_unsigned_vector),
+     rvv_arg_type_info_end};
+
+static CONSTEXPR const rvv_arg_type_info su_qdvv_args[]
+  = {rvv_arg_type_info (RVV_BASE_vector),
+     rvv_arg_type_info (RVV_BASE_quad_lmul1_vector),
+     rvv_arg_type_info (RVV_BASE_quad_fixed_unsigned_vector),
+     rvv_arg_type_info_end};
+
+static CONSTEXPR const rvv_arg_type_info us_qdvv_args[]
+  = {rvv_arg_type_info (RVV_BASE_vector),
+     rvv_arg_type_info (RVV_BASE_quad_lmul1_unsigned_vector),
+     rvv_arg_type_info (RVV_BASE_quad_fixed_vector), rvv_arg_type_info_end};
+
 /* A list of args for vector_type func (signed double demote type,
  * unsigneddouble demote type) function.  */
 static CONSTEXPR const rvv_arg_type_info su_wvv_args[]
@@ -2278,6 +2334,70 @@ static CONSTEXPR const rvv_op_info i_us_wwxv_ops
      rvv_arg_type_info (RVV_BASE_vector), /* Return type */
      us_wwxv_args /* Args */};
 
+/* A static operand information for vector_type func (vector_type, quad demote
+ * type, quad demote type) function registration. */
+static CONSTEXPR const rvv_op_info i_qqvv_ops
+  = {qmacc_ops,                                  /* Types */
+     OP_TYPE_4x8x4,                      /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     qqvv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, quad demote
+ * type, quad demote type) function registration. */
+static CONSTEXPR const rvv_op_info u_qqvv_ops
+  = {qmacc_ops,                                  /* Types */
+     OP_TYPE_4x8x4,                      /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     uqqvv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, quad demote
+ * type, quad demote type) function registration. */
+static CONSTEXPR const rvv_op_info i_su_qqvv_ops
+  = {qmacc_ops,                                  /* Types */
+     OP_TYPE_4x8x4,                      /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     su_qqvv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, quad demote
+ * type, quad demote type) function registration. */
+static CONSTEXPR const rvv_op_info i_us_qqvv_ops
+  = {qmacc_ops,                                  /* Types */
+     OP_TYPE_4x8x4,                      /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     us_qqvv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, quad demote
+ * type, quad demote type) function registration. */
+static CONSTEXPR const rvv_op_info i_qdvv_ops
+  = {qmacc_ops,                                  /* Types */
+     OP_TYPE_2x8x2,                      /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     qdvv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, quad demote
+ * type, quad demote type) function registration. */
+static CONSTEXPR const rvv_op_info u_qdvv_ops
+  = {qmacc_ops,                                  /* Types */
+     OP_TYPE_2x8x2,                      /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     uqdvv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, quad demote
+ * type, quad demote type) function registration. */
+static CONSTEXPR const rvv_op_info i_su_qdvv_ops
+  = {qmacc_ops,                                  /* Types */
+     OP_TYPE_2x8x2,                      /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     su_qdvv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, quad demote
+ * type, quad demote type) function registration. */
+static CONSTEXPR const rvv_op_info i_us_qdvv_ops
+  = {qmacc_ops,                                  /* Types */
+     OP_TYPE_2x8x2,                      /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     us_qdvv_args /* Args */};
+
 /* A static operand information for vector_type func (signed double demote 
type,
  * unsigned double demote type) function registration. */
 static CONSTEXPR const rvv_op_info i_su_wvv_ops
@@ -2863,14 +2983,15 @@ static CONSTEXPR const rvv_op_info 
u_vvvv_crypto_sew64_ops
 static CONSTEXPR const function_type_info function_types[] = {
 #define DEF_RVV_TYPE_INDEX(                                                    
\
   VECTOR, MASK, SIGNED, UNSIGNED, EEW8_INDEX, EEW16_INDEX, EEW32_INDEX,        
\
-  EEW64_INDEX, SHIFT, DOUBLE_TRUNC, QUAD_TRUNC, OCT_TRUNC,                     
\
+  EEW64_INDEX, SHIFT, DOUBLE_TRUNC, QUAD_TRUNC, QUAD_EMUL, QUAD_EMUL_SIGNED,   
\
+  QUAD_EMUL_UNSIGNED, QUAD_FIX, QUAD_FIX_SIGNED, QUAD_FIX_UNSIGNED, OCT_TRUNC, 
\
   DOUBLE_TRUNC_SCALAR, DOUBLE_TRUNC_SIGNED, DOUBLE_TRUNC_UNSIGNED,             
\
-  DOUBLE_TRUNC_UNSIGNED_SCALAR, DOUBLE_TRUNC_BFLOAT_SCALAR,                    
\
-  DOUBLE_TRUNC_BFLOAT, DOUBLE_TRUNC_FLOAT, FLOAT, LMUL1, WLMUL1,               
\
-  EEW8_INTERPRET, EEW16_INTERPRET, EEW32_INTERPRET, EEW64_INTERPRET,           
\
-  BOOL1_INTERPRET, BOOL2_INTERPRET, BOOL4_INTERPRET, BOOL8_INTERPRET,          
\
-  BOOL16_INTERPRET, BOOL32_INTERPRET, BOOL64_INTERPRET,                        
\
-  SIGNED_EEW8_LMUL1_INTERPRET, SIGNED_EEW16_LMUL1_INTERPRET,                   
\
+  DOUBLE_TRUNC_UNSIGNED_SCALAR, DOUBLE_TRUNC_BFLOAT_SCALAR,                    
\
+  DOUBLE_TRUNC_BFLOAT, DOUBLE_TRUNC_FLOAT, FLOAT, LMUL1, WLMUL1, QLMUL1,       
\
+  QLMUL1_SIGNED, QLMUL1_UNSIGNED, EEW8_INTERPRET, EEW16_INTERPRET,             
\
+  EEW32_INTERPRET, EEW64_INTERPRET, BOOL1_INTERPRET, BOOL2_INTERPRET,          
\
+  BOOL4_INTERPRET, BOOL8_INTERPRET, BOOL16_INTERPRET, BOOL32_INTERPRET,        
\
+  BOOL64_INTERPRET, SIGNED_EEW8_LMUL1_INTERPRET, SIGNED_EEW16_LMUL1_INTERPRET, 
\
   SIGNED_EEW32_LMUL1_INTERPRET, SIGNED_EEW64_LMUL1_INTERPRET,                  
\
   UNSIGNED_EEW8_LMUL1_INTERPRET, UNSIGNED_EEW16_LMUL1_INTERPRET,               
\
   UNSIGNED_EEW32_LMUL1_INTERPRET, UNSIGNED_EEW64_LMUL1_INTERPRET,              
\
@@ -2898,17 +3019,26 @@ static CONSTEXPR const function_type_info 
function_types[] = {
     VECTOR_TYPE_##SHIFT,                                                       
\
     VECTOR_TYPE_##DOUBLE_TRUNC,                                                
\
     VECTOR_TYPE_##QUAD_TRUNC,                                                  
\
+    VECTOR_TYPE_##QUAD_EMUL,                                                   
\
+    VECTOR_TYPE_##QUAD_EMUL_SIGNED,                                            
\
+    VECTOR_TYPE_##QUAD_EMUL_UNSIGNED,                                          
\
+    VECTOR_TYPE_##QUAD_FIX,                                                    
\
+    VECTOR_TYPE_##QUAD_FIX_SIGNED,                                             
\
+    VECTOR_TYPE_##QUAD_FIX_UNSIGNED,                                           
\
     VECTOR_TYPE_##OCT_TRUNC,                                                   
\
     VECTOR_TYPE_##DOUBLE_TRUNC_SCALAR,                                         
\
     VECTOR_TYPE_##DOUBLE_TRUNC_SIGNED,                                         
\
     VECTOR_TYPE_##DOUBLE_TRUNC_UNSIGNED,                                       
\
     VECTOR_TYPE_##DOUBLE_TRUNC_UNSIGNED_SCALAR,                                
\
-    VECTOR_TYPE_##DOUBLE_TRUNC_BFLOAT_SCALAR,                                  
\
-    VECTOR_TYPE_##DOUBLE_TRUNC_BFLOAT,                                         
\
+    VECTOR_TYPE_##DOUBLE_TRUNC_BFLOAT_SCALAR,                                  
\
+    VECTOR_TYPE_##DOUBLE_TRUNC_BFLOAT,                                         
\
     VECTOR_TYPE_##DOUBLE_TRUNC_FLOAT,                                          
\
     VECTOR_TYPE_##FLOAT,                                                       
\
     VECTOR_TYPE_##LMUL1,                                                       
\
     VECTOR_TYPE_##WLMUL1,                                                      
\
+    VECTOR_TYPE_##QLMUL1,                                                      
\
+    VECTOR_TYPE_##QLMUL1_SIGNED,                                               
\
+    VECTOR_TYPE_##QLMUL1_UNSIGNED,                                             
\
     VECTOR_TYPE_##EEW8_INTERPRET,                                              
\
     VECTOR_TYPE_##EEW16_INTERPRET,                                             
\
     VECTOR_TYPE_##EEW32_INTERPRET,                                             
\
@@ -2949,6 +3079,9 @@ static function_group_info function_groups[] = {
 #define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO)                         
\
   {#NAME, &bases::NAME, &shapes::SHAPE, PREDS, OPS_INFO, REQUIRED_EXTENSIONS},
 #include "thead-vector-builtins-functions.def"
+#define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO)                         
\
+  {#NAME, &bases::NAME, &shapes::SHAPE, PREDS, OPS_INFO, REQUIRED_EXTENSIONS},
+#include "sifive-vector-builtins-functions.def"
 };
 
 /* The RVV types, with their built-in
diff --git a/gcc/config/riscv/riscv-vector-builtins.def 
b/gcc/config/riscv/riscv-vector-builtins.def
index ffa14d46dbc8..71208450c828 100644
--- a/gcc/config/riscv/riscv-vector-builtins.def
+++ b/gcc/config/riscv/riscv-vector-builtins.def
@@ -70,14 +70,15 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef DEF_RVV_TYPE_INDEX
 #define DEF_RVV_TYPE_INDEX(                                                    
\
   VECTOR, MASK, SIGNED, UNSIGNED, EEW8_INDEX, EEW16_INDEX, EEW32_INDEX,        
\
-  EEW64_INDEX, SHIFT, DOUBLE_TRUNC, QUAD_TRUNC, OCT_TRUNC,                     
\
-  DOUBLE_TRUNC_SCALAR, DOUBLE_TRUNC_SIGNED, DOUBLE_TRUNC_UNSIGNED,             
\
+  EEW64_INDEX, SHIFT, DOUBLE_TRUNC, QUAD_TRUNC, QUAD_EMUL, QUAD_EMUL_SIGNED,   
\
+  QUAD_EMUL_UNSIGNED, QUAD_FIX, QUAD_FIX_SIGNED, QUAD_FIX_UNSIGNED,            
\
+  OCT_TRUNC, DOUBLE_TRUNC_SCALAR, DOUBLE_TRUNC_SIGNED, DOUBLE_TRUNC_UNSIGNED,  
\
   DOUBLE_TRUNC_UNSIGNED_SCALAR, DOUBLE_TRUNC_BFLOAT_SCALAR,                    
\
-  DOUBLE_TRUNC_BFLOAT, DOUBLE_TRUNC_FLOAT, FLOAT, LMUL1, WLMUL1,               
\
-  EEW8_INTERPRET, EEW16_INTERPRET, EEW32_INTERPRET, EEW64_INTERPRET,           
\
-  BOOL1_INTERPRET, BOOL2_INTERPRET, BOOL4_INTERPRET, BOOL8_INTERPRET,          
\
-  BOOL16_INTERPRET, BOOL32_INTERPRET, BOOL64_INTERPRET,                        
\
-  SIGNED_EEW8_LMUL1_INTERPRET, SIGNED_EEW16_LMUL1_INTERPRET,                   
\
+  DOUBLE_TRUNC_BFLOAT, DOUBLE_TRUNC_FLOAT, FLOAT, LMUL1, WLMUL1, QLMUL1,       
\
+  QLMUL1_SIGNED, QLMUL1_UNSIGNED, EEW8_INTERPRET, EEW16_INTERPRET,             
\
+  EEW32_INTERPRET, EEW64_INTERPRET, BOOL1_INTERPRET, BOOL2_INTERPRET,          
\
+  BOOL4_INTERPRET, BOOL8_INTERPRET, BOOL16_INTERPRET, BOOL32_INTERPRET,        
\
+  BOOL64_INTERPRET, SIGNED_EEW8_LMUL1_INTERPRET, SIGNED_EEW16_LMUL1_INTERPRET, 
\
   SIGNED_EEW32_LMUL1_INTERPRET, SIGNED_EEW64_LMUL1_INTERPRET,                  
\
   UNSIGNED_EEW8_LMUL1_INTERPRET, UNSIGNED_EEW16_LMUL1_INTERPRET,               
\
   UNSIGNED_EEW32_LMUL1_INTERPRET, UNSIGNED_EEW64_LMUL1_INTERPRET,              
\
@@ -634,6 +635,8 @@ DEF_RVV_OP_TYPE (xu_v)
 DEF_RVV_OP_TYPE (f_w)
 DEF_RVV_OP_TYPE (xu_w)
 DEF_RVV_OP_TYPE (s)
+DEF_RVV_OP_TYPE (4x8x4)
+DEF_RVV_OP_TYPE (2x8x2)
 
 DEF_RVV_PRED_TYPE (ta)
 DEF_RVV_PRED_TYPE (tu)
@@ -676,6 +679,12 @@ DEF_RVV_BASE_TYPE (eew64_index, get_vector_type (type_idx))
 DEF_RVV_BASE_TYPE (shift_vector, get_vector_type (type_idx))
 DEF_RVV_BASE_TYPE (double_trunc_vector, get_vector_type (type_idx))
 DEF_RVV_BASE_TYPE (quad_trunc_vector, get_vector_type (type_idx))
+DEF_RVV_BASE_TYPE (quad_emul_vector, get_vector_type (type_idx))
+DEF_RVV_BASE_TYPE (quad_emul_signed_vector, get_vector_type (type_idx))
+DEF_RVV_BASE_TYPE (quad_emul_unsigned_vector, get_vector_type (type_idx))
+DEF_RVV_BASE_TYPE (quad_fixed_vector, get_vector_type (type_idx))
+DEF_RVV_BASE_TYPE (quad_fixed_signed_vector, get_vector_type (type_idx))
+DEF_RVV_BASE_TYPE (quad_fixed_unsigned_vector, get_vector_type (type_idx))
 DEF_RVV_BASE_TYPE (oct_trunc_vector, get_vector_type (type_idx))
 DEF_RVV_BASE_TYPE (double_trunc_scalar, get_scalar_type (type_idx))
 DEF_RVV_BASE_TYPE (double_trunc_signed_vector, get_vector_type (type_idx))
@@ -687,6 +696,9 @@ DEF_RVV_BASE_TYPE (double_trunc_float_vector, 
get_vector_type (type_idx))
 DEF_RVV_BASE_TYPE (float_vector, get_vector_type (type_idx))
 DEF_RVV_BASE_TYPE (lmul1_vector, get_vector_type (type_idx))
 DEF_RVV_BASE_TYPE (widen_lmul1_vector, get_vector_type (type_idx))
+DEF_RVV_BASE_TYPE (quad_lmul1_vector, get_vector_type (type_idx))
+DEF_RVV_BASE_TYPE (quad_lmul1_signed_vector, get_vector_type (type_idx))
+DEF_RVV_BASE_TYPE (quad_lmul1_unsigned_vector, get_vector_type (type_idx))
 DEF_RVV_BASE_TYPE (eew8_interpret, get_vector_type (type_idx))
 DEF_RVV_BASE_TYPE (eew16_interpret, get_vector_type (type_idx))
 DEF_RVV_BASE_TYPE (eew32_interpret, get_vector_type (type_idx))
diff --git a/gcc/config/riscv/riscv-vector-builtins.h 
b/gcc/config/riscv/riscv-vector-builtins.h
index f092dbfa3bef..fec024d9f948 100644
--- a/gcc/config/riscv/riscv-vector-builtins.h
+++ b/gcc/config/riscv/riscv-vector-builtins.h
@@ -127,6 +127,8 @@ enum required_ext
   XTHEADVECTOR_EXT,    /* XTheadVector extension */
   ZVFBFMIN_EXT,                /* Zvfbfmin extension */
   ZVFBFWMA_EXT,                /* Zvfbfwma extension */
+  XSFVQMACCQOQ_EXT,    /* XSFVQMACCQOQ extension */
+  XSFVQMACCDOD_EXT,    /* XSFVQMACCDOD extension */
   /* Please update below to isa_name func when add or remove enum type(s).  */
 };
 
@@ -160,6 +162,10 @@ static inline const char * required_ext_to_isa_name (enum 
required_ext required)
       return "zvfbfmin";
     case ZVFBFWMA_EXT:
       return "zvfbfwma";
+    case XSFVQMACCQOQ_EXT:
+      return "xsfvqmaccqoq";
+    case XSFVQMACCDOD_EXT:
+      return "xsfvqmaccdod";
     default:
       gcc_unreachable ();
   }
@@ -197,6 +203,10 @@ static inline bool required_extensions_specified (enum 
required_ext required)
       return TARGET_ZVFBFMIN;
     case ZVFBFWMA_EXT:
       return TARGET_ZVFBFWMA;
+    case XSFVQMACCQOQ_EXT:
+      return TARGET_XSFVQMACCQOQ;
+    case XSFVQMACCDOD_EXT:
+      return TARGET_XSFVQMACCDOD;
     default:
       gcc_unreachable ();
   }
@@ -337,6 +347,10 @@ struct function_group_info
        return TARGET_ZVFBFMIN;
       case ZVFBFWMA_EXT:
        return TARGET_ZVFBFWMA;
+      case XSFVQMACCQOQ_EXT:
+       return TARGET_XSFVQMACCQOQ;
+      case XSFVQMACCDOD_EXT:
+       return TARGET_XSFVQMACCDOD;
       default:
         gcc_unreachable ();
     }
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index f7a6db354af5..afde5294467f 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -475,6 +475,8 @@
 ;; vfncvtbf16  vector narrowing single floating-point to brain floating-point 
instruction
 ;; vfwcvtbf16  vector widening brain floating-point to single floating-point 
instruction
 ;; vfwmaccbf16  vector BF16 widening multiply-accumulate
+;; SiFive custom extension instrctions
+;; sf_vqmacc      vector matrix integer multiply-add instructions
 (define_attr "type"
   "unknown,branch,jump,jalr,ret,call,load,fpload,store,fpstore,
    mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
@@ -485,7 +487,7 @@
    vldux,vldox,vstux,vstox,vldff,vldr,vstr,
    
vlsegde,vssegte,vlsegds,vssegts,vlsegdux,vlsegdox,vssegtux,vssegtox,vlsegdff,
    vialu,viwalu,vext,vicalu,vshift,vnshift,vicmp,viminmax,
-   vimul,vidiv,viwmul,vimuladd,viwmuladd,vimerge,vimov,
+   vimul,vidiv,viwmul,vimuladd,sf_vqmacc,viwmuladd,vimerge,vimov,
    vsalu,vaalu,vsmul,vsshift,vnclip,
    vfalu,vfwalu,vfmul,vfdiv,vfwmul,vfmuladd,vfwmuladd,vfsqrt,vfrecp,
    vfcmp,vfminmax,vfsgnj,vfclass,vfmerge,vfmov,
diff --git a/gcc/config/riscv/sifive-vector-builtins-bases.cc 
b/gcc/config/riscv/sifive-vector-builtins-bases.cc
new file mode 100644
index 000000000000..c219f9f705f3
--- /dev/null
+++ b/gcc/config/riscv/sifive-vector-builtins-bases.cc
@@ -0,0 +1,164 @@
+/* function_base implementation for SiFive custom 'V' Extension for GNU 
compiler.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   Contributed by SiFive and PLCT Lab.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "memmodel.h"
+#include "insn-codes.h"
+#include "optabs.h"
+#include "recog.h"
+#include "expr.h"
+#include "basic-block.h"
+#include "function.h"
+#include "fold-const.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify.h"
+#include "explow.h"
+#include "emit-rtl.h"
+#include "tree-vector-builder.h"
+#include "rtx-vector-builder.h"
+#include "riscv-vector-builtins.h"
+#include "riscv-vector-builtins-shapes.h"
+#include "sifive-vector-builtins-bases.h"
+
+using namespace riscv_vector;
+
+namespace riscv_vector {
+
+/* Implements SiFive vqmacc.  */
+class sf_vqmacc : public function_base
+{
+public:
+  bool has_merge_operand_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+  bool use_mask_predication_p () const override { return false; }
+  bool can_be_overloaded_p (enum predication_type_index pred) const override
+  {
+    return pred == PRED_TYPE_tu;
+  }
+
+  rtx expand (function_expander &e) const override
+  {
+    if (e.op_info->op == OP_TYPE_4x8x4)
+      return e.use_widen_ternop_insn (
+       code_for_pred_matrix_mul_plus_qoq (SIGN_EXTEND, e.vector_mode ()));
+    if (e.op_info->op == OP_TYPE_2x8x2)
+      return e.use_widen_ternop_insn (
+       code_for_pred_matrix_mul_plus_dod (SIGN_EXTEND, e.vector_mode ()));
+    gcc_unreachable ();
+  }
+};
+
+/* Implements SiFive vqmaccu.  */
+class sf_vqmaccu : public function_base
+{
+public:
+  bool has_merge_operand_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+  bool use_mask_predication_p () const override { return false; }
+
+  bool can_be_overloaded_p (enum predication_type_index pred) const override
+  {
+    return pred == PRED_TYPE_tu;
+  }
+
+  rtx expand (function_expander &e) const override
+  {
+    if (e.op_info->op == OP_TYPE_4x8x4)
+      return e.use_widen_ternop_insn (
+       code_for_pred_matrix_mul_plus_qoq (ZERO_EXTEND, e.vector_mode ()));
+    if (e.op_info->op == OP_TYPE_2x8x2)
+      return e.use_widen_ternop_insn (
+       code_for_pred_matrix_mul_plus_dod (ZERO_EXTEND, e.vector_mode ()));
+    gcc_unreachable ();
+  }
+};
+
+/* Implements SiFive vqmaccsu.  */
+class sf_vqmaccsu : public function_base
+{
+public:
+  bool has_merge_operand_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+  bool use_mask_predication_p () const override { return false; }
+
+  bool can_be_overloaded_p (enum predication_type_index pred) const override
+  {
+    return pred == PRED_TYPE_tu;
+  }
+
+  rtx expand (function_expander &e) const override
+  {
+    if (e.op_info->op == OP_TYPE_4x8x4)
+      return e.use_widen_ternop_insn (
+       code_for_pred_matrix_mul_plussu_qoq (e.vector_mode ()));
+    if (e.op_info->op == OP_TYPE_2x8x2)
+      return e.use_widen_ternop_insn (
+       code_for_pred_matrix_mul_plussu_dod (e.vector_mode ()));
+    gcc_unreachable ();
+  }
+};
+
+/* Implements SiFive vqmaccus.  */
+class sf_vqmaccus : public function_base
+{
+public:
+  bool has_merge_operand_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+  bool use_mask_predication_p () const override { return false; }
+
+  bool can_be_overloaded_p (enum predication_type_index pred) const override
+  {
+    return pred == PRED_TYPE_tu;
+  }
+
+  rtx expand (function_expander &e) const override
+  {
+    if (e.op_info->op == OP_TYPE_4x8x4)
+      return e.use_widen_ternop_insn (
+       code_for_pred_matrix_mul_plusus_qoq (e.vector_mode ()));
+    if (e.op_info->op == OP_TYPE_2x8x2)
+      return e.use_widen_ternop_insn (
+       code_for_pred_matrix_mul_plusus_dod (e.vector_mode ()));
+    gcc_unreachable ();
+  }
+};
+
+static CONSTEXPR const sf_vqmacc sf_vqmacc_obj;
+static CONSTEXPR const sf_vqmaccu sf_vqmaccu_obj;
+static CONSTEXPR const sf_vqmaccsu sf_vqmaccsu_obj;
+static CONSTEXPR const sf_vqmaccus sf_vqmaccus_obj;
+
+/* Declare the function base NAME, pointing it to an instance
+   of class <NAME>_obj.  */
+#define BASE(NAME) \
+  namespace bases { const function_base *const NAME = &NAME##_obj; }
+
+BASE (sf_vqmacc)
+BASE (sf_vqmaccu)
+BASE (sf_vqmaccsu)
+BASE (sf_vqmaccus)
+} // end namespace riscv_vector
diff --git a/gcc/config/riscv/sifive-vector-builtins-bases.h 
b/gcc/config/riscv/sifive-vector-builtins-bases.h
new file mode 100644
index 000000000000..f6b8347a341a
--- /dev/null
+++ b/gcc/config/riscv/sifive-vector-builtins-bases.h
@@ -0,0 +1,35 @@
+/* function_base declaration for SiFive custom 'V' Extension for GNU compiler.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   Contributed by SiFive and PLCT Lab.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_SIFIVE_VECTOR_BUILTINS_BASES_H
+#define GCC_SIFIVE_VECTOR_BUILTINS_BASES_H
+
+namespace riscv_vector {
+
+namespace bases {
+extern const function_base *const sf_vqmacc;
+extern const function_base *const sf_vqmaccu;
+extern const function_base *const sf_vqmaccsu;
+extern const function_base *const sf_vqmaccus;
+}
+
+} // end namespace riscv_vector
+
+#endif
diff --git a/gcc/config/riscv/sifive-vector-builtins-functions.def 
b/gcc/config/riscv/sifive-vector-builtins-functions.def
new file mode 100644
index 000000000000..9b666fdeaff9
--- /dev/null
+++ b/gcc/config/riscv/sifive-vector-builtins-functions.def
@@ -0,0 +1,54 @@
+/* Intrinsic define macros for SiFive custom 'V' Extension for GNU compiler.
+   Copyright (C) 2024 Free Software Foundation, Inc.
+   Contributed by SiFive and PLCT Lab.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* Use "DEF_RVV_FUNCTION" macro to define RVV intrinsic functions.
+
+     - NAME not only describes the base_name of the functions
+       but also point to the name of the function_base class.
+
+     - SHAPE point to the function_shape class.
+
+     - PREDS describes the predication types that are supported in the
+       functions.
+
+     - OPS_INFO describes all information of return type and each
+       argument type.
+
+*/
+#ifndef DEF_RVV_FUNCTION
+#define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO)
+#endif
+
+#define REQUIRED_EXTENSIONS XSFVQMACCQOQ_EXT
+DEF_RVV_FUNCTION (sf_vqmacc, sf_vqmacc, none_tu_preds, i_qqvv_ops)
+DEF_RVV_FUNCTION (sf_vqmaccu, sf_vqmacc, none_tu_preds, u_qqvv_ops)
+DEF_RVV_FUNCTION (sf_vqmaccsu, sf_vqmacc, none_tu_preds, i_su_qqvv_ops)
+DEF_RVV_FUNCTION (sf_vqmaccus, sf_vqmacc, none_tu_preds, i_us_qqvv_ops)
+#undef REQUIRED_EXTENSIONS
+
+#define REQUIRED_EXTENSIONS XSFVQMACCDOD_EXT
+DEF_RVV_FUNCTION (sf_vqmacc, sf_vqmacc, none_tu_preds, i_qdvv_ops)
+DEF_RVV_FUNCTION (sf_vqmaccu, sf_vqmacc, none_tu_preds, u_qdvv_ops)
+DEF_RVV_FUNCTION (sf_vqmaccsu, sf_vqmacc, none_tu_preds, i_su_qdvv_ops)
+DEF_RVV_FUNCTION (sf_vqmaccus, sf_vqmacc, none_tu_preds, i_us_qdvv_ops)
+
+#undef REQUIRED_EXTENSIONS
+
+#undef DEF_RVV_FUNCTION
diff --git a/gcc/config/riscv/sifive-vector.md 
b/gcc/config/riscv/sifive-vector.md
new file mode 100644
index 000000000000..2cc631eee53c
--- /dev/null
+++ b/gcc/config/riscv/sifive-vector.md
@@ -0,0 +1,164 @@
+;; Machine description for RISC-V for GNU compiler.
+;; Copyright (C) 2024 Free Software Foundation, Inc.
+;; Contributed by SiFive and PLCT Lab.
+;; Based on RISC-V target for GNU compiler.
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_insn "@pred_matrix_mul_plus<u><mode>_qoq"
+  [(set (match_operand:SF_VSI 0 "register_operand"                    "=&vr")
+       (if_then_else:SF_VSI
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand"             "vmWc1")
+            (match_operand 5 "vector_length_operand"                "   rK")
+            (match_operand 6 "const_int_operand"                    "    i")
+            (match_operand 7 "const_int_operand"                    "    i")
+            (match_operand 8 "const_int_operand"                    "    i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (plus:SF_VSI
+           (mult:SF_VSI
+             (any_extend:SF_VSI
+               (match_operand:RVVM1QI 3 "register_operand" "   vr"))
+             (any_extend:SF_VSI
+               (match_operand:<SF_VQMACC_QOQ> 4 "register_operand" "   vr")))
+           (match_operand:SF_VSI 2 "register_operand"              "    0"))
+         (match_dup 2)))]
+  "TARGET_VECTOR && TARGET_XSFVQMACCQOQ"
+  "sf.vqmacc<u>.4x8x4\t%0,%3,%4"
+  [(set_attr "type" "sf_vqmacc")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_matrix_mul_plussu<mode>_qoq"
+  [(set (match_operand:SF_VSI 0 "register_operand"                    "=&vr")
+       (if_then_else:SF_VSI
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand"             "vmWc1")
+            (match_operand 5 "vector_length_operand"                "   rK")
+            (match_operand 6 "const_int_operand"                    "    i")
+            (match_operand 7 "const_int_operand"                    "    i")
+            (match_operand 8 "const_int_operand"                    "    i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (plus:SF_VSI
+           (mult:SF_VSI
+             (sign_extend:SF_VSI
+               (match_operand:RVVM1QI 3 "register_operand" "   vr"))
+             (zero_extend:SF_VSI
+               (match_operand:<SF_VQMACC_QOQ> 4 "register_operand" "   vr")))
+           (match_operand:SF_VSI 2 "register_operand"              "    0"))
+         (match_dup 2)))]
+  "TARGET_VECTOR && TARGET_XSFVQMACCQOQ"
+  "sf.vqmaccsu.4x8x4\t%0,%3,%4"
+  [(set_attr "type" "sf_vqmacc")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_matrix_mul_plusus<mode>_qoq"
+  [(set (match_operand:SF_VSI 0 "register_operand"                    "=&vr")
+       (if_then_else:SF_VSI
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand"             "vmWc1")
+            (match_operand 5 "vector_length_operand"                "   rK")
+            (match_operand 6 "const_int_operand"                    "    i")
+            (match_operand 7 "const_int_operand"                    "    i")
+            (match_operand 8 "const_int_operand"                    "    i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (plus:SF_VSI
+           (mult:SF_VSI
+             (zero_extend:SF_VSI
+               (match_operand:RVVM1QI 3 "register_operand" "   vr"))
+             (sign_extend:SF_VSI
+               (match_operand:<SF_VQMACC_QOQ> 4 "register_operand" "   vr")))
+           (match_operand:SF_VSI 2 "register_operand"              "    0"))
+         (match_dup 2)))]
+  "TARGET_VECTOR && TARGET_XSFVQMACCQOQ"
+  "sf.vqmaccus.4x8x4\t%0,%3,%4"
+  [(set_attr "type" "sf_vqmacc")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_matrix_mul_plus<u><mode>_dod"
+  [(set (match_operand:SF_VSI 0 "register_operand"                    "=&vr")
+       (if_then_else:SF_VSI
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand"             "vmWc1")
+            (match_operand 5 "vector_length_operand"                "   rK")
+            (match_operand 6 "const_int_operand"                    "    i")
+            (match_operand 7 "const_int_operand"                    "    i")
+            (match_operand 8 "const_int_operand"                    "    i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (plus:SF_VSI
+           (mult:SF_VSI
+             (any_extend:SF_VSI
+               (match_operand:RVVM1QI 3 "register_operand" "   vr"))
+             (any_extend:SF_VSI
+               (match_operand:<SF_VQMACC_DOD> 4 "register_operand" "   vr")))
+           (match_operand:SF_VSI 2 "register_operand"              "    0"))
+         (match_dup 2)))]
+  "TARGET_VECTOR && TARGET_XSFVQMACCDOD"
+  "sf.vqmacc<u>.2x8x2\t%0,%3,%4"
+  [(set_attr "type" "sf_vqmacc")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_matrix_mul_plussu<mode>_dod"
+  [(set (match_operand:SF_VSI 0 "register_operand"                    "=&vr")
+       (if_then_else:SF_VSI
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand"             "vmWc1")
+            (match_operand 5 "vector_length_operand"                "   rK")
+            (match_operand 6 "const_int_operand"                    "    i")
+            (match_operand 7 "const_int_operand"                    "    i")
+            (match_operand 8 "const_int_operand"                    "    i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (plus:SF_VSI
+           (mult:SF_VSI
+             (sign_extend:SF_VSI
+               (match_operand:RVVM1QI 3 "register_operand" "   vr"))
+             (zero_extend:SF_VSI
+               (match_operand:<SF_VQMACC_DOD> 4 "register_operand" "   vr")))
+           (match_operand:SF_VSI 2 "register_operand"              "    0"))
+         (match_dup 2)))]
+  "TARGET_VECTOR && TARGET_XSFVQMACCDOD"
+  "sf.vqmaccsu.2x8x2\t%0,%3,%4"
+  [(set_attr "type" "sf_vqmacc")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_matrix_mul_plusus<mode>_dod"
+  [(set (match_operand:SF_VSI 0 "register_operand"                    "=&vr")
+       (if_then_else:SF_VSI
+         (unspec:<VM>
+           [(match_operand:<VM> 1 "vector_mask_operand"             "vmWc1")
+            (match_operand 5 "vector_length_operand"                "   rK")
+            (match_operand 6 "const_int_operand"                    "    i")
+            (match_operand 7 "const_int_operand"                    "    i")
+            (match_operand 8 "const_int_operand"                    "    i")
+            (reg:SI VL_REGNUM)
+            (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+         (plus:SF_VSI
+           (mult:SF_VSI
+             (zero_extend:SF_VSI
+               (match_operand:RVVM1QI 3 "register_operand" "   vr"))
+             (sign_extend:SF_VSI
+               (match_operand:<SF_VQMACC_DOD> 4 "register_operand" "   vr")))
+           (match_operand:SF_VSI 2 "register_operand"              "    0"))
+         (match_dup 2)))]
+  "TARGET_VECTOR && TARGET_XSFVQMACCDOD"
+  "sf.vqmaccus.2x8x2\t%0,%3,%4"
+  [(set_attr "type" "sf_vqmacc")
+   (set_attr "mode" "<MODE>")])
diff --git a/gcc/config/riscv/t-riscv b/gcc/config/riscv/t-riscv
index 38494320d8b2..bc67d8719fa5 100644
--- a/gcc/config/riscv/t-riscv
+++ b/gcc/config/riscv/t-riscv
@@ -2,6 +2,7 @@ RISCV_BUILTINS_H = 
$(srcdir)/config/riscv/riscv-vector-builtins.h \
                   $(srcdir)/config/riscv/riscv-vector-builtins.def \
                   $(srcdir)/config/riscv/riscv-vector-builtins-functions.def \
        $(srcdir)/config/riscv/thead-vector-builtins-functions.def \
+       $(srcdir)/config/riscv/sifive-vector-builtins-functions.def \
                   riscv-vector-type-indexer.gen.def
 
 riscv-builtins.o: $(srcdir)/config/riscv/riscv-builtins.cc $(CONFIG_H) \
@@ -9,6 +10,7 @@ riscv-builtins.o: $(srcdir)/config/riscv/riscv-builtins.cc 
$(CONFIG_H) \
   $(DIAGNOSTIC_CORE_H) $(OPTABS_H) $(RISCV_BUILTINS_H) \
   $(srcdir)/config/riscv/riscv-ftypes.def \
   $(srcdir)/config/riscv/riscv-vector-builtins-types.def \
+  $(srcdir)/config/riscv/sifive-vector-builtins-functions.def \
   $(srcdir)/config/riscv/riscv-modes.def \
   $(srcdir)/config/riscv/riscv-cmo.def \
   $(srcdir)/config/riscv/riscv-scalar-crypto.def
@@ -23,7 +25,9 @@ riscv-vector-builtins.o: 
$(srcdir)/config/riscv/riscv-vector-builtins.cc \
   gimple.h gimple-iterator.h \
   $(srcdir)/config/riscv/riscv-vector-builtins-shapes.h \
   $(srcdir)/config/riscv/riscv-vector-builtins-bases.h \
+  $(srcdir)/config/riscv/sifive-vector-builtins-bases.h \
   $(srcdir)/config/riscv/riscv-vector-builtins-types.def \
+  $(srcdir)/config/riscv/sifive-vector-builtins-functions.def \
   $(RISCV_BUILTINS_H)
        $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
                $(srcdir)/config/riscv/riscv-vector-builtins.cc
@@ -34,6 +38,7 @@ riscv-vector-builtins-shapes.o: \
   $(TM_P_H) memmodel.h insn-codes.h $(OPTABS_H) \
   $(srcdir)/config/riscv/riscv-vector-builtins-shapes.h \
   $(srcdir)/config/riscv/riscv-vector-builtins-bases.h \
+  $(srcdir)/config/riscv/sifive-vector-builtins-bases.h \
   $(RISCV_BUILTINS_H)
        $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
                $(srcdir)/config/riscv/riscv-vector-builtins-shapes.cc
@@ -51,6 +56,19 @@ riscv-vector-builtins-bases.o: \
        $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
                $(srcdir)/config/riscv/riscv-vector-builtins-bases.cc
 
+sifive-vector-builtins-bases.o: \
+  $(srcdir)/config/riscv/sifive-vector-builtins-bases.cc \
+  $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
+  $(TM_P_H) memmodel.h insn-codes.h $(OPTABS_H) $(RECOG_H) \
+  $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) fold-const.h $(GIMPLE_H) \
+  gimple-iterator.h gimplify.h explow.h $(EMIT_RTL_H) tree-vector-builder.h \
+  rtx-vector-builder.h \
+  $(srcdir)/config/riscv/riscv-vector-builtins-shapes.h \
+  $(srcdir)/config/riscv/sifive-vector-builtins-bases.h \
+  $(RISCV_BUILTINS_H)
+       $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+               $(srcdir)/config/riscv/sifive-vector-builtins-bases.cc
+
 riscv-sr.o: $(srcdir)/config/riscv/riscv-sr.cc $(CONFIG_H) \
   $(SYSTEM_H) $(TM_H)
        $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
@@ -142,6 +160,8 @@ build/genrvv-type-indexer$(build_exeext): 
build/genrvv-type-indexer.o
 
 $(srcdir)/config/riscv/riscv-vector-builtins.def: 
riscv-vector-type-indexer.gen.def
 $(srcdir)/config/riscv/riscv-vector-builtins.h: 
$(srcdir)/config/riscv/riscv-vector-builtins.def
+$(srcdir)/config/riscv/sifive-vector-builtins-functions.def: 
riscv-vector-type-indexer.gen.def
+$(srcdir)/config/riscv/riscv-vector-builtins.h: 
$(srcdir)/config/riscv/sifive-vector-builtins-functions.def
 
 riscv-vector-type-indexer.gen.def: s-riscv-vector-type-indexer.gen.defs ; @true
 
diff --git a/gcc/config/riscv/vector-iterators.md 
b/gcc/config/riscv/vector-iterators.md
index 92cb651ce493..cf6b38216538 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -4755,3 +4755,35 @@
   (V256DF "v64df")
   (V512DF "v128df")
 ])
+
+(define_mode_iterator SF_VSI [
+  RVVM8SI RVVM4SI RVVM2SI RVVM1SI
+])
+
+(define_mode_attr SF_VQMACC_QOQ [
+  (RVVM8SI "RVVM4QI")
+  (RVVM4SI "RVVM2QI")
+  (RVVM2SI "RVVM1QI")
+  (RVVM1SI "RVVMF2QI")
+])
+
+(define_mode_attr sf_vqmacc_qoq [
+  (RVVM8SI "rvvm4qi")
+  (RVVM4SI "rvvm2qi")
+  (RVVM2SI "rvvm1qi")
+  (RVVM1SI "rvvmf2qi")
+])
+
+(define_mode_attr SF_VQMACC_DOD [
+  (RVVM8SI "RVVM8QI")
+  (RVVM4SI "RVVM4QI")
+  (RVVM2SI "RVVM2QI")
+  (RVVM1SI "RVVM1QI")
+])
+
+(define_mode_attr sf_vqmacc_dod [
+  (RVVM8SI "rvvm8qi")
+  (RVVM4SI "rvvm4qi")
+  (RVVM2SI "rvvm2qi")
+  (RVVM1SI "rvvm1qi")
+])
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 57e3c34c1c5a..a3b46ba751ea 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -8564,3 +8564,4 @@
 
 (include "autovec.md")
 (include "autovec-opt.md")
+(include "sifive-vector.md")

Reply via email to