[1/2] RISC-V: Add support for XCVmac extension in CV32E40P

Message ID 20230919150734.2854664-2-mary.bennett@embecosm.com
State Unresolved
Headers
Series RISC-V: Support CORE-V XCVMAC and XCVALU extensions |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Mary Bennett Sept. 19, 2023, 3:07 p.m. UTC
  Spec: github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md

Contributors:
      Mary Bennett <mary.bennett@embecosm.com>
      Nandni Jamnadas <nandni.jamnadas@embecosm.com>
      Pietra Ferreira <pietra.ferreira@embecosm.com>
      Charlie Keaney
      Jessica Mills
      Craig Blackmore <craig.blackmore@embecosm.com>
      Simon Cook <simon.cook@embecosm.com>
      Jeremy Bennett <jeremy.bennett@embecosm.com>
      Helene Chelin <helene.chelin@embecosm.com>

gcc/ChangeLog:

	* common/config/riscv/riscv-common.cc: Added XCVmac.
	* config/riscv/riscv-ftypes.def: Added XCVmac builtins.
	* config/riscv/riscv-opts.h: Likewise.
	* config/riscv/riscv.md: Likewise.
	* config/riscv/riscv.opt: Likewise.
	* doc/extend.texi: Added XCVmac builtin documentation.
	* config/riscv/corev.def: New file.
	* config/riscv/corev.md: New file.

gcc/testsuite/ChangeLog:

	* lib/target-supports.exp: Added new effective target check.
	* gcc.target/riscv/cv-mac-compile.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-mac.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-machhsn.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-machhsrn.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-machhun.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-machhurn.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-macsn.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-macsrn.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-macun.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-macurn.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-msu.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-mulhhsn.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-mulhhsrn.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-mulhhun.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-mulhhurn.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-mulsn.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-mulsrn.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-mulun.c: New test.
	* gcc.target/riscv/cv-mac-fail-compile-mulurn.c: New test.
	* gcc.target/riscv/cv-mac-test-autogeneration.c: New test.
---
 gcc/common/config/riscv/riscv-common.cc       |   4 +
 gcc/config/riscv/corev.def                    |  19 +
 gcc/config/riscv/corev.md                     | 390 ++++++++++++++++++
 gcc/config/riscv/riscv-builtins.cc            |  10 +
 gcc/config/riscv/riscv-ftypes.def             |   5 +
 gcc/config/riscv/riscv-opts.h                 |   5 +
 gcc/config/riscv/riscv.md                     |   1 +
 gcc/config/riscv/riscv.opt                    |   3 +
 gcc/doc/extend.texi                           |  80 ++++
 .../gcc.target/riscv/cv-mac-compile.c         | 198 +++++++++
 .../riscv/cv-mac-fail-compile-mac.c           |  25 ++
 .../riscv/cv-mac-fail-compile-machhsn.c       |  24 ++
 .../riscv/cv-mac-fail-compile-machhsrn.c      |  24 ++
 .../riscv/cv-mac-fail-compile-machhun.c       |  24 ++
 .../riscv/cv-mac-fail-compile-machhurn.c      |  24 ++
 .../riscv/cv-mac-fail-compile-macsn.c         |  24 ++
 .../riscv/cv-mac-fail-compile-macsrn.c        |  24 ++
 .../riscv/cv-mac-fail-compile-macun.c         |  24 ++
 .../riscv/cv-mac-fail-compile-macurn.c        |  24 ++
 .../riscv/cv-mac-fail-compile-msu.c           |  25 ++
 .../riscv/cv-mac-fail-compile-mulhhsn.c       |  24 ++
 .../riscv/cv-mac-fail-compile-mulhhsrn.c      |  24 ++
 .../riscv/cv-mac-fail-compile-mulhhun.c       |  24 ++
 .../riscv/cv-mac-fail-compile-mulhhurn.c      |  24 ++
 .../riscv/cv-mac-fail-compile-mulsn.c         |  24 ++
 .../riscv/cv-mac-fail-compile-mulsrn.c        |  24 ++
 .../riscv/cv-mac-fail-compile-mulun.c         |  24 ++
 .../riscv/cv-mac-fail-compile-mulurn.c        |  24 ++
 .../riscv/cv-mac-test-autogeneration.c        |  18 +
 gcc/testsuite/lib/target-supports.exp         |  13 +
 30 files changed, 1180 insertions(+)
 create mode 100644 gcc/config/riscv/corev.def
 create mode 100644 gcc/config/riscv/corev.md
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-compile.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mac.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhsn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhsrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-machhurn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macsn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macsrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-macurn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-msu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhsn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhsrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulhhurn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulsn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulsrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-fail-compile-mulurn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-mac-test-autogeneration.c
  

Patch

diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 9a0a68fe5db..53e21fa4bce 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_flags, 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..59aeafe485f
--- /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-opts.h b/gcc/config/riscv/riscv-opts.h
index a525f679683..8b0aa1d1b41 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -295,6 +295,8 @@  enum riscv_entity
    ? 0 \
    : 32 << (__builtin_popcount (riscv_zvl_flags) - 1))
 
+#define MASK_XCVMAC    (1 <<  0)
+
 #define MASK_XTHEADBA      (1 << 0)
 #define MASK_XTHEADBB      (1 << 1)
 #define MASK_XTHEADBS      (1 << 2)
@@ -308,6 +310,9 @@  enum riscv_entity
 #define MASK_XTHEADMEMPAIR (1 << 10)
 #define MASK_XTHEADSYNC    (1 << 11)
 
+
+#define TARGET_XCVMAC    ((riscv_xcv_flags & MASK_XCVMAC) != 0)
+
 #define TARGET_XTHEADBA      ((riscv_xthead_subext & MASK_XTHEADBA) != 0)
 #define TARGET_XTHEADBB      ((riscv_xthead_subext & MASK_XTHEADBB) != 0)
 #define TARGET_XTHEADBS      ((riscv_xthead_subext & MASK_XTHEADBS) != 0)
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index e00b8ee3579..7cee9ba94f0 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3590,3 +3590,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 21d00606f25..10076982f09 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -254,6 +254,9 @@  int riscv_sv_subext
 TargetVariable
 int riscv_ztso_subext
 
+TargetVariable
+int riscv_xcv_flags
+
 TargetVariable
 int riscv_xthead_subext
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 947c05babc9..f6753de0028 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -14909,6 +14909,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::
@@ -21651,6 +21652,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/testsuite/gcc.target/riscv/cv-mac-compile.c b/gcc/testsuite/gcc.target/riscv/cv-mac-compile.c
new file mode 100644
index 00000000000..573638a909b
--- /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 2de41cef2f6..45baf112983 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -12656,6 +12656,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 } {