diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 9a0a68fe5db..62de116803e 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -310,6 +310,8 @@ static const struct riscv_ext_version riscv_ext_version_table[] =
   {"svnapot", ISA_SPEC_CLASS_NONE, 1, 0},
   {"svpbmt",  ISA_SPEC_CLASS_NONE, 1, 0},
 
+  {"xcvmac", ISA_SPEC_CLASS_NONE, 1, 0},
+
   {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadbs", ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1480,6 +1482,8 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
 
   {"ztso", &gcc_options::x_riscv_ztso_subext, MASK_ZTSO},
 
+  {"xcvmac",        &gcc_options::x_riscv_xcv_subext, MASK_XCVMAC},
+
   {"xtheadba",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBA},
   {"xtheadbb",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBB},
   {"xtheadbs",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBS},
diff --git a/gcc/config/riscv/corev.def b/gcc/config/riscv/corev.def
new file mode 100644
index 00000000000..a4e94680d8e
--- /dev/null
+++ b/gcc/config/riscv/corev.def
@@ -0,0 +1,19 @@
+// XCVMAC
+RISCV_BUILTIN (cv_mac_mac,       "cv_mac_mac",    RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_SI,      cvmac),
+RISCV_BUILTIN (cv_mac_msu,       "cv_mac_msu",    RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_SI,      cvmac),
+RISCV_BUILTIN (cv_mac_muluN,     "cv_mac_muluN",      RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvmac),
+RISCV_BUILTIN (cv_mac_mulhhuN,   "cv_mac_mulhhuN",    RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvmac),
+RISCV_BUILTIN (cv_mac_mulsN,     "cv_mac_mulsN",      RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI,     cvmac),
+RISCV_BUILTIN (cv_mac_mulhhsN,   "cv_mac_mulhhsN",    RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI,     cvmac),
+RISCV_BUILTIN (cv_mac_muluRN,    "cv_mac_muluRN",     RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvmac),
+RISCV_BUILTIN (cv_mac_mulhhuRN,  "cv_mac_mulhhuRN",   RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvmac),
+RISCV_BUILTIN (cv_mac_mulsRN,    "cv_mac_mulsRN",     RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI,     cvmac),
+RISCV_BUILTIN (cv_mac_mulhhsRN,  "cv_mac_mulhhsRN",   RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI,     cvmac),
+RISCV_BUILTIN (cv_mac_macuN,     "cv_mac_macuN",      RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_USI_UQI,  cvmac),
+RISCV_BUILTIN (cv_mac_machhuN,   "cv_mac_machhuN",    RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_USI_UQI,  cvmac),
+RISCV_BUILTIN (cv_mac_macsN,     "cv_mac_macsN",      RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_SI_UQI,      cvmac),
+RISCV_BUILTIN (cv_mac_machhsN,   "cv_mac_machhsN",    RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_SI_UQI,      cvmac),
+RISCV_BUILTIN (cv_mac_macuRN,    "cv_mac_macuRN",     RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_USI_UQI,  cvmac),
+RISCV_BUILTIN (cv_mac_machhuRN,  "cv_mac_machhuRN",   RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_USI_UQI,  cvmac),
+RISCV_BUILTIN (cv_mac_macsRN,    "cv_mac_macsRN",     RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_SI_UQI,      cvmac),
+RISCV_BUILTIN (cv_mac_machhsRN,  "cv_mac_machhsRN",   RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_SI_UQI,      cvmac),
diff --git a/gcc/config/riscv/corev.md b/gcc/config/riscv/corev.md
new file mode 100644
index 00000000000..65ce09ea6eb
--- /dev/null
+++ b/gcc/config/riscv/corev.md
@@ -0,0 +1,390 @@
+;; Machine description for CORE-V vendor extensions.
+;; Copyright (C) 2023 Free Software Foundation, Inc.
+
+;; 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/>.
+
+;; XCVMAC extension.
+
+(define_insn "riscv_cv_mac_mac"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+                          (match_operand:SI 2 "register_operand" "r"))
+                 (match_operand:SI 3 "register_operand" "0")))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.mac\t%0,%1,%2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_msu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (minus:SI (match_operand:SI 3 "register_operand" "0")
+                  (mult:SI (match_operand:SI 1 "register_operand" "r")
+                           (match_operand:SI 2 "register_operand" "r"))))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.msu\t%0,%1,%2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_muluN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (lshiftrt:SI
+      (mult:SI
+        (zero_extend:SI
+          (truncate:HI
+            (match_operand:SI 1 "register_operand" "r")))
+        (zero_extend:SI
+          (truncate:HI
+            (match_operand:SI 2 "register_operand" "r"))))
+      (match_operand:QI 3 "const_csr_operand" "K")))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.mulun\t%0,%1,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_mulhhuN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (lshiftrt:SI
+      (mult:SI
+        (zero_extend:SI
+          (truncate:HI
+            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+                         (const_int 16))))
+        (zero_extend:SI
+          (truncate:HI
+            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+                         (const_int 16)))))
+      (match_operand:QI 3 "const_csr_operand" "K")))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.mulhhun\t%0,%1,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_mulsN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (ashiftrt:SI
+      (mult:SI
+        (sign_extend:SI
+          (truncate:HI
+            (match_operand:SI 1 "register_operand" "r")))
+        (sign_extend:SI
+          (truncate:HI
+            (match_operand:SI 2 "register_operand" "r"))))
+      (match_operand:QI 3 "const_csr_operand" "K")))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.mulsn\t%0,%1,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_mulhhsN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (ashiftrt:SI
+      (mult:SI
+        (sign_extend:SI
+          (truncate:HI
+            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+                         (const_int 16))))
+        (sign_extend:SI
+          (truncate:HI
+            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+                         (const_int 16)))))
+      (match_operand:QI 3 "const_csr_operand" "K")))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.mulhhsn\t%0,%1,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_muluRN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (lshiftrt:SI
+      (fma:SI
+        (zero_extend:SI
+          (truncate:HI
+            (match_operand:SI 1 "register_operand" "r")))
+        (zero_extend:SI
+          (truncate:HI
+            (match_operand:SI 2 "register_operand" "r")))
+        (if_then_else
+          (ne:QI (match_operand:QI 3 "const_csr_operand" "K") (const_int 0))
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))
+          (const_int 0)))
+      (match_dup 3)))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.mulurn\t%0,%1,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_mulhhuRN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (lshiftrt:SI
+      (fma:SI
+        (zero_extend:SI
+          (truncate:HI
+            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+                         (const_int 16))))
+        (zero_extend:SI
+          (truncate:HI
+            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+                         (const_int 16))))
+        (if_then_else
+          (ne:QI (match_operand:QI 3 "const_csr_operand" "K") (const_int 0))
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))
+          (const_int 0)))
+      (match_dup 3)))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.mulhhurn\t%0,%1,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_mulsRN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (ashiftrt:SI
+      (fma:SI
+        (sign_extend:SI
+          (truncate:HI
+            (match_operand:SI 1 "register_operand" "r")))
+        (sign_extend:SI
+          (truncate:HI
+            (match_operand:SI 2 "register_operand" "r")))
+        (if_then_else
+          (ne:QI (match_operand:QI 3 "const_csr_operand" "K") (const_int 0))
+          (ashift:SI (const_int 1)
+                     (minus:QI (match_dup 3)
+                               (const_int 1)))
+          (const_int 0)))
+      (match_dup 3)))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.mulsrn\t%0,%1,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_mulhhsRN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (ashiftrt:SI
+      (fma:SI
+        (sign_extend:SI
+          (truncate:HI
+            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+                         (const_int 16))))
+        (sign_extend:SI
+          (truncate:HI
+            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+                         (const_int 16))))
+        (if_then_else
+          (ne:QI (match_operand:QI 3 "const_csr_operand" "K") (const_int 0))
+          (ashift:SI (const_int 1)
+                     (minus:QI (match_dup 3)
+                               (const_int 1)))
+          (const_int 0)))
+      (match_dup 3)))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.mulhhsrn\t%0,%1,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_macuN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (lshiftrt:SI
+      (fma:SI
+        (zero_extend:SI
+          (truncate:HI
+            (match_operand:SI 1 "register_operand" "r")))
+        (zero_extend:SI
+          (truncate:HI
+            (match_operand:SI 2 "register_operand" "r")))
+        (match_operand:SI 3 "register_operand" "0"))
+      (match_operand:QI 4 "const_csr_operand" "K")))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.macun\t%0,%1,%2,%4"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_machhuN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (lshiftrt:SI
+      (fma:SI
+        (zero_extend:SI
+          (truncate:HI
+            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+                         (const_int 16))))
+        (zero_extend:SI
+          (truncate:HI
+            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+                         (const_int 16))))
+        (match_operand:SI 3 "register_operand" "0"))
+      (match_operand:QI 4 "const_csr_operand" "K")))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.machhun\t%0,%1,%2,%4"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_macsN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (ashiftrt:SI
+      (fma:SI
+        (sign_extend:SI
+          (truncate:HI
+            (match_operand:SI 1 "register_operand" "r")))
+        (sign_extend:SI
+          (truncate:HI
+            (match_operand:SI 2 "register_operand" "r")))
+        (match_operand:SI 3 "register_operand" "0"))
+      (match_operand:QI 4 "const_csr_operand" "K")))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.macsn\t%0,%1,%2,%4"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_machhsN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (ashiftrt:SI
+      (fma:SI
+        (sign_extend:SI
+          (truncate:HI
+            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+                         (const_int 16))))
+        (sign_extend:SI
+          (truncate:HI
+            (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+                         (const_int 16))))
+        (match_operand:SI 3 "register_operand" "0"))
+      (match_operand:QI 4 "const_csr_operand" "K")))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.machhsn\t%0,%1,%2,%4"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_macuRN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (lshiftrt:SI
+      (plus:SI
+        (fma:SI
+          (zero_extend:SI
+            (truncate:HI
+              (match_operand:SI 1 "register_operand" "r")))
+          (zero_extend:SI
+            (truncate:HI
+              (match_operand:SI 2 "register_operand" "r")))
+          (match_operand:SI 3 "register_operand" "0"))
+        (if_then_else
+          (ne:QI (match_operand:QI 4 "const_csr_operand" "K") (const_int 0))
+          (ashift:SI (const_int 1)
+                     (minus:QI (match_dup 4)
+                               (const_int 1)))
+          (const_int 0)))
+      (match_dup 4)))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.macurn\t%0,%1,%2,%4"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_machhuRN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (lshiftrt:SI
+      (plus:SI
+        (fma:SI
+          (zero_extend:SI
+            (truncate:HI
+              (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+                           (const_int 16))))
+          (zero_extend:SI
+            (truncate:HI
+              (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+                           (const_int 16))))
+          (match_operand:SI 3 "register_operand" "0"))
+        (if_then_else
+          (ne:QI (match_operand:QI 4 "const_csr_operand" "K") (const_int 0))
+          (ashift:SI (const_int 1)
+                     (minus:QI (match_dup 4)
+                               (const_int 1)))
+          (const_int 0)))
+      (match_dup 4)))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.machhurn\t%0,%1,%2,%4"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_macsRN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (ashiftrt:SI
+      (plus:SI
+        (fma:SI
+          (sign_extend:SI
+            (truncate:HI
+              (match_operand:SI 1 "register_operand" "r")))
+          (sign_extend:SI
+            (truncate:HI
+              (match_operand:SI 2 "register_operand" "r")))
+          (match_operand:SI 3 "register_operand" "0"))
+        (if_then_else
+          (ne:QI (match_operand:QI 4 "const_csr_operand" "K") (const_int 0))
+          (ashift:SI (const_int 1)
+                     (minus:QI (match_dup 4)
+                               (const_int 1)))
+          (const_int 0)))
+      (match_dup 4)))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.macsrn\t%0,%1,%2,%4"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_mac_machhsRN"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (ashiftrt:SI
+      (plus:SI
+        (fma:SI
+          (sign_extend:SI
+            (truncate:HI
+              (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+                           (const_int 16))))
+          (sign_extend:SI
+            (truncate:HI
+              (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+                           (const_int 16))))
+          (match_operand:SI 3 "register_operand" "0"))
+        (if_then_else
+          (ne:QI (match_operand:QI 4 "const_csr_operand" "K") (const_int 0))
+          (ashift:SI (const_int 1)
+                     (minus:QI (match_dup 4)
+                               (const_int 1)))
+          (const_int 0)))
+      (match_dup 4)))]
+
+  "TARGET_XCVMAC && !TARGET_64BIT"
+  "cv.machhsrn\t%0,%1,%2,%4"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc
index 3fe3a89dcc2..1f733337b82 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -47,6 +47,8 @@ along with GCC; see the file COPYING3.  If not see
 #define RISCV_FTYPE_NAME1(A, B) RISCV_##A##_FTYPE_##B
 #define RISCV_FTYPE_NAME2(A, B, C) RISCV_##A##_FTYPE_##B##_##C
 #define RISCV_FTYPE_NAME3(A, B, C, D) RISCV_##A##_FTYPE_##B##_##C##_##D
+#define RISCV_FTYPE_NAME4(A, B, C, D, E) \
+  RISCV_##A##_FTYPE_##B##_##C##_##D##_##E
 
 /* Classifies the prototype of a built-in function.  */
 enum riscv_function_type {
@@ -123,6 +125,9 @@ AVAIL (clmulr_zbc32, TARGET_ZBC && !TARGET_64BIT)
 AVAIL (clmulr_zbc64, TARGET_ZBC && TARGET_64BIT)
 AVAIL (hint_pause, (!0))
 
+// CORE-V AVAIL
+AVAIL (cvmac, TARGET_XCVMAC && !TARGET_64BIT)
+
 /* Construct a riscv_builtin_description from the given arguments.
 
    INSN is the name of the associated instruction pattern, without the
@@ -158,6 +163,7 @@ AVAIL (hint_pause, (!0))
 #define RISCV_ATYPE_UHI unsigned_intHI_type_node
 #define RISCV_ATYPE_USI unsigned_intSI_type_node
 #define RISCV_ATYPE_UDI unsigned_intDI_type_node
+#define RISCV_ATYPE_SI intSI_type_node
 #define RISCV_ATYPE_VOID_PTR ptr_type_node
 
 /* RISCV_FTYPE_ATYPESN takes N RISCV_FTYPES-like type codes and lists
@@ -170,10 +176,14 @@ AVAIL (hint_pause, (!0))
   RISCV_ATYPE_##A, RISCV_ATYPE_##B, RISCV_ATYPE_##C
 #define RISCV_FTYPE_ATYPES3(A, B, C, D) \
   RISCV_ATYPE_##A, RISCV_ATYPE_##B, RISCV_ATYPE_##C, RISCV_ATYPE_##D
+#define RISCV_FTYPE_ATYPES4(A, B, C, D, E) \
+  RISCV_ATYPE_##A, RISCV_ATYPE_##B, RISCV_ATYPE_##C, RISCV_ATYPE_##D, \
+  RISCV_ATYPE_##E
 
 static const struct riscv_builtin_description riscv_builtins[] = {
   #include "riscv-cmo.def"
   #include "riscv-scalar-crypto.def"
+  #include "corev.def"
 
   DIRECT_BUILTIN (frflags, RISCV_USI_FTYPE, hard_float),
   DIRECT_NO_TARGET_BUILTIN (fsflags, RISCV_VOID_FTYPE_USI, hard_float),
diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def
index 33620c57ca0..430a4c2d673 100644
--- a/gcc/config/riscv/riscv-ftypes.def
+++ b/gcc/config/riscv/riscv-ftypes.def
@@ -40,4 +40,9 @@ DEF_RISCV_FTYPE (2, (UDI, UHI, UHI))
 DEF_RISCV_FTYPE (2, (UDI, USI, USI))
 DEF_RISCV_FTYPE (2, (UDI, UDI, USI))
 DEF_RISCV_FTYPE (2, (UDI, UDI, UDI))
+DEF_RISCV_FTYPE (3, (USI, USI, USI, UQI))
 DEF_RISCV_FTYPE (3, (USI, USI, USI, USI))
+DEF_RISCV_FTYPE (3, (SI, SI, SI, UQI))
+DEF_RISCV_FTYPE (3, (SI, SI, SI, SI))
+DEF_RISCV_FTYPE (4, (USI, USI, USI, USI, UQI))
+DEF_RISCV_FTYPE (4, (SI, SI, SI, SI, UQI))
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 76bc4e760ff..c26541bd5ce 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3620,3 +3620,4 @@
 (include "vector.md")
 (include "zicond.md")
 (include "zc.md")
+(include "corev.md")
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index e35ce2de364..f838f6ec55f 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -404,6 +404,11 @@ int riscv_ztso_subext
 
 Mask(ZTSO) Var(riscv_ztso_subext)
 
+TargetVariable
+int riscv_xcv_subext
+
+Mask(XCVMAC) Var(riscv_xcv_subext)
+
 TargetVariable
 int riscv_xthead_subext
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index b82497f00e4..d71397310df 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -14970,6 +14970,7 @@ instructions, but allow the compiler to schedule those calls.
 * PRU Built-in Functions::
 * RISC-V Built-in Functions::
 * RISC-V Vector Intrinsics::
+* CORE-V Built-in Functions::
 * RX Built-in Functions::
 * S/390 System z Built-in Functions::
 * SH Built-in Functions::
@@ -21712,6 +21713,85 @@ vector intrinsic specification, which is available at the following link:
 @uref{https://github.com/riscv-non-isa/rvv-intrinsic-doc/tree/v0.11.x}.
 All of these functions are declared in the include file @file{riscv_vector.h}.
 
+@node CORE-V Built-in Functions
+@subsubsection CORE-V Built-in Functions
+
+These built-in functions are available for the CORE-V MAC machine
+architecture. For more information on CORE-V built-ins, please see
+@uref{https://github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md#listing-of-multiply-accumulate-builtins-xcvmac}.
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_mac_mac (int32_t, int32_t, int32_t)
+Generated assembler @code{cv.mac}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_mac_msu (int32_t, int32_t, int32_t)
+Generates the @code{cv.msu} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_mac_muluN (uint32_t, uint32_t, uint8_t)
+Generates the @code{cv.muluN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_mac_mulhhuN (uint32_t, uint32_t, uint8_t)
+Generates the @code{cv.mulhhuN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_mac_mulsN (int32_t, int32_t, uint8_t)
+Generates the @code{cv.mulsN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_mac_mulhhsN (int32_t, int32_t, uint8_t)
+Generates the @code{cv.mulhhsN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_mac_muluRN (uint32_t, uint32_t, uint8_t)
+Generates the @code{cv.muluRN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_mac_mulhhuRN (uint32_t, uint32_t, uint8_t)
+Generates the @code{cv.mulhhuRN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_mac_mulsRN (int32_t, int32_t, uint8_t)
+Generates the @code{cv.mulsRN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_mac_mulhhsRN (int32_t, int32_t, uint8_t)
+Generates the @code{cv.mulhhsRN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_mac_macuN (uint32_t, uint32_t, uint8_t)
+Generates the @code{cv.macuN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_mac_machhuN (uint32_t, uint32_t, uint8_t)
+Generates the @code{cv.machhuN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_mac_macsN (int32_t, int32_t, uint8_t)
+Generates the @code{cv.macsN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_mac_machhsN (int32_t, int32_t, uint8_t)
+Generates the @code{cv.machhsN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_mac_macuRN (uint32_t, uint32_t, uint8_t)
+Generates the @code{cv.macuRN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_mac_machhuRN (uint32_t, uint32_t, uint8_t)
+Generates the @code{cv.machhuRN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_mac_macsRN (int32_t, int32_t, uint8_t)
+Generates the @code{cv.macsRN} machine instruction.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_mac_machhsRN (int32_t, int32_t, uint8_t)
+Generates the @code{cv.machhsRN} machine instruction.
+@end deftypefn
+
 @node RX Built-in Functions
 @subsection RX Built-in Functions
 GCC supports some of the RX instructions which cannot be expressed in
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 8bf701461ec..1e1e61a5d67 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -2471,6 +2471,15 @@ Test system has an integer register width of 64 bits.
 
 @end table
 
+@subsubsection CORE-V specific attributes
+
+@table @code
+
+@item cv_mac
+Test system has support for the CORE-V MAC extension.
+
+@end table
+
 @subsubsection Other hardware attributes
 
 @c Please keep this table sorted alphabetically.
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-compile.c b/gcc/testsuite/gcc.target/riscv/cv-mac-compile.c
new file mode 100644
index 00000000000..c5d4320ebf0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-compile.c
@@ -0,0 +1,198 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+
+extern int d;
+extern int e;
+extern int f;
+
+int 
+foo0(int a, int b, int c)
+{
+  return __builtin_riscv_cv_mac_mac (a, b, c);
+}
+
+void 
+foo1(int a, int b, int c)
+{
+  d = __builtin_riscv_cv_mac_machhsN (a, b, c, 0);
+  e = __builtin_riscv_cv_mac_machhsN (a, b, c, 7);
+  f = __builtin_riscv_cv_mac_machhsN (a, b, c, 31);
+}
+
+void 
+foo2(int a, int b, int c)
+{
+  d = __builtin_riscv_cv_mac_machhsRN (a, b, c, 0);
+  e = __builtin_riscv_cv_mac_machhsRN (a, b, c, 7);
+  f = __builtin_riscv_cv_mac_machhsRN (a, b, c, 31);
+}
+
+void 
+foo3(int a, int b, int c)
+{
+  d = __builtin_riscv_cv_mac_machhuN (a, b, c, 0);
+  e = __builtin_riscv_cv_mac_machhuN (a, b, c, 7);
+  f = __builtin_riscv_cv_mac_machhuN (a, b, c, 31);
+}
+
+void 
+foo4(int a, int b, int c)
+{
+  d = __builtin_riscv_cv_mac_machhuRN (a, b, c, 0);
+  e = __builtin_riscv_cv_mac_machhuRN (a, b, c, 7);
+  f = __builtin_riscv_cv_mac_machhuRN (a, b, c, 31);
+}
+
+void 
+foo5(int a, int b, int c)
+{
+  d = __builtin_riscv_cv_mac_macsN (a, b, c, 0);
+  e = __builtin_riscv_cv_mac_macsN (a, b, c, 7);
+  f = __builtin_riscv_cv_mac_macsN (a, b, c, 31);
+}
+
+void 
+foo6(int a, int b, int c)
+{
+  d = __builtin_riscv_cv_mac_macsRN (a, b, c, 0);
+  e = __builtin_riscv_cv_mac_macsRN (a, b, c, 7);
+  f = __builtin_riscv_cv_mac_macsRN (a, b, c, 31);
+}
+
+void 
+foo7(int a, int b, int c)
+{
+  d = __builtin_riscv_cv_mac_macuN (a, b, c, 0);
+  e = __builtin_riscv_cv_mac_macuN (a, b, c, 7);
+  f = __builtin_riscv_cv_mac_macuN (a, b, c, 31);
+}
+
+void 
+foo8(int a, int b, int c)
+{
+  d = __builtin_riscv_cv_mac_macuRN (a, b, c, 0);
+  e = __builtin_riscv_cv_mac_macuRN (a, b, c, 7);
+  f = __builtin_riscv_cv_mac_macuRN (a, b, c, 31);
+}
+
+int 
+foo9(int a, int b, int c)
+{
+  return __builtin_riscv_cv_mac_msu (a, b, c);
+}
+
+void 
+foo10(int a, int b)
+{
+  d = __builtin_riscv_cv_mac_mulhhsN (a, b, 0);
+  e = __builtin_riscv_cv_mac_mulhhsN (a, b, 7);
+  f = __builtin_riscv_cv_mac_mulhhsN (a, b, 31);
+}
+
+void 
+foo11(int a, int b)
+{
+  d = __builtin_riscv_cv_mac_mulhhsRN (a, b, 0);
+  e = __builtin_riscv_cv_mac_mulhhsRN (a, b, 7);
+  f = __builtin_riscv_cv_mac_mulhhsRN (a, b, 31);
+}
+
+void 
+foo12(int a, int b)
+{
+  d = __builtin_riscv_cv_mac_mulhhuN (a, b, 0);
+  e = __builtin_riscv_cv_mac_mulhhuN (a, b, 7);
+  f = __builtin_riscv_cv_mac_mulhhuN (a, b, 31);
+}
+
+void 
+foo13(int a, int b)
+{
+  d = __builtin_riscv_cv_mac_mulhhuRN (a, b, 0);
+  e = __builtin_riscv_cv_mac_mulhhuRN (a, b, 7);
+  f = __builtin_riscv_cv_mac_mulhhuRN (a, b, 31);
+}
+
+void 
+foo14(int a, int b)
+{
+  d = __builtin_riscv_cv_mac_mulsN (a, b, 0);
+  e = __builtin_riscv_cv_mac_mulsN (a, b, 7);
+  f = __builtin_riscv_cv_mac_mulsN (a, b, 31);
+}
+
+void 
+foo15(int a, int b)
+{
+  d = __builtin_riscv_cv_mac_mulsRN (a, b, 0);
+  e = __builtin_riscv_cv_mac_mulsRN (a, b, 7);
+  f = __builtin_riscv_cv_mac_mulsRN (a, b, 31);
+}
+
+void 
+foo16(int a, int b)
+{
+  d = __builtin_riscv_cv_mac_muluN (a, b, 0);
+  e = __builtin_riscv_cv_mac_muluN (a, b, 7);
+  f = __builtin_riscv_cv_mac_muluN (a, b, 31);
+}
+
+void 
+foo17(int a, int b)
+{
+  d = __builtin_riscv_cv_mac_muluRN (a, b, 0);
+  e = __builtin_riscv_cv_mac_muluRN (a, b, 7);
+  f = __builtin_riscv_cv_mac_muluRN (a, b, 31);
+}
+
+/* { dg-final { scan-assembler-times "cv\.mac\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\)" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.machhsn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.machhsn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.machhsn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.machhsrn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.machhsrn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.machhsrn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.machhun\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.machhun\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.machhun\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.machhurn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.machhurn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.machhurn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.macsn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.macsn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.macsn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.macsrn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.macsrn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.macsrn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.macun\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.macun\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.macun\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.macurn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.macurn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.macurn\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.msu\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\)" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulhhsn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulhhsn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulhhsn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulhhsrn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulhhsrn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulhhsrn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulhhun\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulhhun\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulhhun\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulhhurn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulhhurn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulhhurn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulsn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulsn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulsn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulsn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulsn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulsn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulun\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulun\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulun\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulurn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulurn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],7" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.mulurn\t\[a-z\]\[0-9\],\[a-z\]\[0-9\],\[a-z\]\[0-9\],31" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mac.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mac.c
new file mode 100644
index 00000000000..cfb1ed8874f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mac.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+
+#include <stdint.h>
+
+extern int32_t res1;
+extern int32_t res2;
+extern int32_t res3;
+extern int32_t res4;
+extern int32_t res5;
+extern int32_t res6;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_mac (12147483649, 21, 47); /* { dg-warning "overflow in conversion" } */
+  res2 = __builtin_riscv_cv_mac_mac (648, 12147483649, 48); /* { dg-warning "overflow in conversion" } */
+  res3 = __builtin_riscv_cv_mac_mac (648, 48, 12147483649); /* { dg-warning "overflow in conversion" } */
+  res4 = __builtin_riscv_cv_mac_mac (-2147483649, 21, 47); /* { dg-warning "overflow in conversion" } */
+  res5 = __builtin_riscv_cv_mac_mac (648, -2147483649, 48); /* { dg-warning "overflow in conversion" } */
+  res6 = __builtin_riscv_cv_mac_mac (648, 48, -2147483649); /* { dg-warning "overflow in conversion" } */
+
+  return res1+res2+res3+res4+res5+res6;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhsn.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhsn.c
new file mode 100644
index 00000000000..32c5329ac13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhsn.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */ 
+
+#include <stdint.h>
+
+extern int32_t res1;
+extern int32_t res2;
+extern int32_t res3;
+extern int32_t res4;
+extern int32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_machhsN (648, 219, 319, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_machhsN (648, 219, 325, 0);
+  res3 = __builtin_riscv_cv_mac_machhsN (648, 219, 319, 15);
+  res4 = __builtin_riscv_cv_mac_machhsN (648, 219, 325, 31);
+  res5 = __builtin_riscv_cv_mac_machhsN (648, 219, 325, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhsrn.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhsrn.c
new file mode 100644
index 00000000000..1b8e4e5bc63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhsrn.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern int32_t res1;
+extern int32_t res2;
+extern int32_t res3;
+extern int32_t res4;
+extern int32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_machhsRN (648, 219, 319, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_machhsRN (648, 219, 325, 0);
+  res3 = __builtin_riscv_cv_mac_machhsRN (648, 219, 319, 15);
+  res4 = __builtin_riscv_cv_mac_machhsRN (648, 219, 325, 31);
+  res5 = __builtin_riscv_cv_mac_machhsRN (648, 219, 325, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhun.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhun.c
new file mode 100644
index 00000000000..08cb17a458b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhun.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+extern uint32_t res4;
+extern uint32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_machhuN (648, 219, 319, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_machhuN (648, 219, 325, 0);
+  res3 = __builtin_riscv_cv_mac_machhuN (648, 219, 319, 15);
+  res4 = __builtin_riscv_cv_mac_machhuN (648, 219, 325, 31);
+  res5 = __builtin_riscv_cv_mac_machhuN (648, 219, 325, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhurn.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhurn.c
new file mode 100644
index 00000000000..cbfc8ee71c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhurn.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+extern uint32_t res4;
+extern uint32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_machhuRN (648, 219, 319, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_machhuRN (648, 219, 325, 0);
+  res3 = __builtin_riscv_cv_mac_machhuRN (648, 219, 319, 15);
+  res4 = __builtin_riscv_cv_mac_machhuRN (648, 219, 325, 31);
+  res5 = __builtin_riscv_cv_mac_machhuRN (648, 219, 325, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macsn.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macsn.c
new file mode 100644
index 00000000000..6ea3f397f1c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macsn.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern int32_t res1;
+extern int32_t res2;
+extern int32_t res3;
+extern int32_t res4;
+extern int32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_macsN (648, 219, 319, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_macsN (648, 219, 325, 0);
+  res3 = __builtin_riscv_cv_mac_macsN (648, 219, 319, 15);
+  res4 = __builtin_riscv_cv_mac_macsN (648, 219, 325, 31);
+  res5 = __builtin_riscv_cv_mac_macsN (648, 219, 325, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macsrn.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macsrn.c
new file mode 100644
index 00000000000..1862846cf84
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macsrn.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern int32_t res1;
+extern int32_t res2;
+extern int32_t res3;
+extern int32_t res4;
+extern int32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_macsRN (648, 219, 319, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_macsRN (648, 219, 325, 0);
+  res3 = __builtin_riscv_cv_mac_macsRN (648, 219, 319, 15);
+  res4 = __builtin_riscv_cv_mac_macsRN (648, 219, 325, 31);
+  res5 = __builtin_riscv_cv_mac_macsRN (648, 219, 325, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macun.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macun.c
new file mode 100644
index 00000000000..58c139a790e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macun.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+extern uint32_t res4;
+extern uint32_t res5;
+
+int 
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_macuN (648, 219, 319, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_macuN (648, 219, 325, 0);
+  res3 = __builtin_riscv_cv_mac_macuN (648, 219, 319, 15);
+  res4 = __builtin_riscv_cv_mac_macuN (648, 219, 325, 31);
+  res5 = __builtin_riscv_cv_mac_macuN (648, 219, 325, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macurn.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macurn.c
new file mode 100644
index 00000000000..65f7b143a48
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macurn.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+extern uint32_t res4;
+extern uint32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_macuRN (648, 219, 319, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_macuRN (648, 219, 325, 0);
+  res3 = __builtin_riscv_cv_mac_macuRN (648, 219, 319, 15);
+  res4 = __builtin_riscv_cv_mac_macuRN (648, 219, 325, 31);
+  res5 = __builtin_riscv_cv_mac_macuRN (648, 219, 325, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-msu.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-msu.c
new file mode 100644
index 00000000000..caee5ebf929
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-msu.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+
+#include <stdint.h>
+
+extern int32_t res1;
+extern int32_t res2;
+extern int32_t res3;
+extern int32_t res4;
+extern int32_t res5;
+extern int32_t res6;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_msu (12147483649, 21, 47); /* { dg-warning "overflow in conversion" } */
+  res2 = __builtin_riscv_cv_mac_msu (648, 12147483649, 48); /* { dg-warning "overflow in conversion" } */
+  res3 = __builtin_riscv_cv_mac_msu (648, 48, 12147483649); /* { dg-warning "overflow in conversion" } */
+  res4 = __builtin_riscv_cv_mac_msu (-2147483649, 21, 47); /* { dg-warning "overflow in conversion" } */
+  res5 = __builtin_riscv_cv_mac_msu (648, -2147483649, 48); /* { dg-warning "overflow in conversion" } */
+  res6 = __builtin_riscv_cv_mac_msu (648, 48, -2147483649); /* { dg-warning "overflow in conversion" } */
+
+  return res1+res2+res3+res4+res5+res6;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhsn.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhsn.c
new file mode 100644
index 00000000000..dd00ab35178
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhsn.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern int32_t res1;
+extern int32_t res2;
+extern int32_t res3;
+extern int32_t res4;
+extern int32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_mulhhsN (648, 219, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_mulhhsN (648, 219, 0);
+  res3 = __builtin_riscv_cv_mac_mulhhsN (648, 219, 15);
+  res4 = __builtin_riscv_cv_mac_mulhhsN (648, 219, 31);
+  res5 = __builtin_riscv_cv_mac_mulhhsN (648, 219, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhsrn.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhsrn.c
new file mode 100644
index 00000000000..c1c1d08fe49
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhsrn.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern int32_t res1;
+extern int32_t res2;
+extern int32_t res3;
+extern int32_t res4;
+extern int32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_mulhhsRN (648, 219, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_mulhhsRN (648, 219, 0);
+  res3 = __builtin_riscv_cv_mac_mulhhsRN (648, 219, 15);
+  res4 = __builtin_riscv_cv_mac_mulhhsRN (648, 219, 31);
+  res5 = __builtin_riscv_cv_mac_mulhhsRN (648, 219, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhun.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhun.c
new file mode 100644
index 00000000000..0516b6f3f17
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhun.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+extern uint32_t res4;
+extern uint32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_mulhhuN (648, 219, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_mulhhuN (648, 219, 0);
+  res3 = __builtin_riscv_cv_mac_mulhhuN (648, 219, 15);
+  res4 = __builtin_riscv_cv_mac_mulhhuN (648, 219, 31);
+  res5 = __builtin_riscv_cv_mac_mulhhuN (648, 219, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhurn.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhurn.c
new file mode 100644
index 00000000000..d605bc65e95
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhurn.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+extern uint32_t res4;
+extern uint32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_mulhhuRN (648, 219, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_mulhhuRN (648, 219, 0);
+  res3 = __builtin_riscv_cv_mac_mulhhuRN (648, 219, 15);
+  res4 = __builtin_riscv_cv_mac_mulhhuRN (648, 219, 31);
+  res5 = __builtin_riscv_cv_mac_mulhhuRN (648, 219, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulsn.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulsn.c
new file mode 100644
index 00000000000..9bcf2b4f70f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulsn.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern int32_t res1;
+extern int32_t res2;
+extern int32_t res3;
+extern int32_t res4;
+extern int32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_mulsN (648, 219, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_mulsN (648, 219, 0);
+  res3 = __builtin_riscv_cv_mac_mulsN (648, 219, 15);
+  res4 = __builtin_riscv_cv_mac_mulsN (648, 219, 31);
+  res5 = __builtin_riscv_cv_mac_mulsN (648, 219, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulsrn.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulsrn.c
new file mode 100644
index 00000000000..2af1065e688
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulsrn.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern int32_t res1;
+extern int32_t res2;
+extern int32_t res3;
+extern int32_t res4;
+extern int32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_mulsRN (648, 219, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_mulsRN (648, 219, 0);
+  res3 = __builtin_riscv_cv_mac_mulsRN (648, 219, 15);
+  res4 = __builtin_riscv_cv_mac_mulsRN (648, 219, 31);
+  res5 = __builtin_riscv_cv_mac_mulsRN (648, 219, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulun.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulun.c
new file mode 100644
index 00000000000..8ed53f53c8c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulun.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+extern uint32_t res4;
+extern uint32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_muluN (648, 219, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_muluN (648, 219, 0);
+  res3 = __builtin_riscv_cv_mac_muluN (648, 219, 15);
+  res4 = __builtin_riscv_cv_mac_muluN (648, 219, 31);
+  res5 = __builtin_riscv_cv_mac_muluN (648, 219, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulurn.c b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulurn.c
new file mode 100644
index 00000000000..b3b8a3df342
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulurn.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-march=rv32i_xcvmac -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+extern uint32_t res4;
+extern uint32_t res5;
+
+int
+main (void)
+{
+  res1 = __builtin_riscv_cv_mac_muluRN (648, 219, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_mac_muluRN (648, 219, 0);
+  res3 = __builtin_riscv_cv_mac_muluRN (648, 219, 15);
+  res4 = __builtin_riscv_cv_mac_muluRN (648, 219, 31);
+  res5 = __builtin_riscv_cv_mac_muluRN (648, 219, 32); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4+res5;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-mac-test-autogeneration.c b/gcc/testsuite/gcc.target/riscv/cv-mac-test-autogeneration.c
new file mode 100644
index 00000000000..1ee9c268ec9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-mac-test-autogeneration.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_mac } */
+/* { dg-options "-O2 -march=rv32im_xcvmac -mabi=ilp32" } */
+
+int
+foo0(int a, int b, int c)
+{
+    return a * b + c;
+}
+
+int
+foo1(int a, int b, int c)
+{
+    return a - b * c;
+}
+
+/* { dg-final { scan-assembler-times "cv\\.mac" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.msu" 1 } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 8037dbcee53..498903557e5 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -12915,6 +12915,19 @@ proc check_effective_target_const_volatile_readonly_section { } {
   return 1
 }
 
+# Return 1 if the CORE-V MAC extension is available.
+proc check_effective_target_cv_mac { } {
+    if { !([istarget riscv*-*-*]) } {
+         return 0
+     }
+    return [check_no_compiler_messages cv_mac object {
+        void foo (void)
+        {
+          asm ("cv.mac t0, t1, t2");
+        }
+    } "-march=rv32i_xcvmac" ]
+}
+
 # Appends necessary Python flags to extra-tool-flags if Python.h is supported.
 # Otherwise, modifies dg-do-what.
 proc dg-require-python-h { args } {
