public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions
@ 2023-09-19 15:07 Mary Bennett
  2023-09-19 15:07 ` [PATCH 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Mary Bennett @ 2023-09-19 15:07 UTC (permalink / raw)
  To: gcc-patches

This patch series presents the comprehensive implementation of the MAC and ALU
extension for CORE-V.

Tested with riscv-gnu-toolchain on binutils, ld, gas and gcc testsuites to
ensure its correctness and compatibility with the existing codebase.
However, your input, reviews, and suggestions are invaluable in making this
extension even more robust.

The CORE-V builtins are described in the specification [1] and work can be
found in the OpenHW group's Github repository [2].

[1] github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md

[2] github.com/openhwgroup/corev-gcc

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>

  RISC-V: Add support for XCValu extension in CV32E40P
  RISC-V: Add support for XCVmac extension in CV32E40P

 gcc/common/config/riscv/riscv-common.cc       |   6 +
 gcc/config/riscv/constraints.md               |   7 +
 gcc/config/riscv/corev.def                    |  43 ++
 gcc/config/riscv/corev.md                     | 675 ++++++++++++++++++
 gcc/config/riscv/predicates.md                |   5 +
 gcc/config/riscv/riscv-builtins.cc            |  13 +
 gcc/config/riscv/riscv-ftypes.def             |  11 +
 gcc/config/riscv/riscv-opts.h                 |   7 +
 gcc/config/riscv/riscv.cc                     |   7 +
 gcc/config/riscv/riscv.md                     |   1 +
 gcc/config/riscv/riscv.opt                    |   3 +
 gcc/doc/extend.texi                           | 174 +++++
 .../gcc.target/riscv/cv-alu-compile.c         | 252 +++++++
 .../riscv/cv-alu-fail-compile-addn.c          |  11 +
 .../riscv/cv-alu-fail-compile-addrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-addun.c         |  11 +
 .../riscv/cv-alu-fail-compile-addurn.c        |  11 +
 .../riscv/cv-alu-fail-compile-clip.c          |  11 +
 .../riscv/cv-alu-fail-compile-clipu.c         |  11 +
 .../riscv/cv-alu-fail-compile-subn.c          |  11 +
 .../riscv/cv-alu-fail-compile-subrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-subun.c         |  11 +
 .../riscv/cv-alu-fail-compile-suburn.c        |  11 +
 .../gcc.target/riscv/cv-alu-fail-compile.c    |  32 +
 .../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         |  26 +
 45 files changed, 2022 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-alu-compile.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
 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

-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/2] RISC-V: Add support for XCVmac extension in CV32E40P
  2023-09-19 15:07 [PATCH 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
@ 2023-09-19 15:07 ` Mary Bennett
  2023-09-19 15:07 ` [PATCH 2/2] RISC-V: Add support for XCValu " Mary Bennett
  2023-09-27 12:26 ` [PATCH v2 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
  2 siblings, 0 replies; 15+ messages in thread
From: Mary Bennett @ 2023-09-19 15:07 UTC (permalink / raw)
  To: gcc-patches

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

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 } {
-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 2/2] RISC-V: Add support for XCValu extension in CV32E40P
  2023-09-19 15:07 [PATCH 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
  2023-09-19 15:07 ` [PATCH 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
@ 2023-09-19 15:07 ` Mary Bennett
  2023-09-23  9:04   ` Kito Cheng
  2023-09-27 12:26 ` [PATCH v2 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
  2 siblings, 1 reply; 15+ messages in thread
From: Mary Bennett @ 2023-09-19 15:07 UTC (permalink / raw)
  To: gcc-patches

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 the XCValu
          extension.
	* config/riscv/constraints.md: Added builtins for the XCValu
          extension.
	* config/riscv/predicates.md (immediate_register_operand):
          Likewise.
	* config/riscv/riscv-builtins.cc (AVAIL): Likewise.
	  (RISCV_ATYPE_UHI): Likewise.
	* config/riscv/riscv-ftypes.def: Likewise.
	* config/riscv/riscv-opts.h: Likewise.
	* config/riscv/riscv.opt: Likewise.
        * config/riscv/riscv.cc (riscv_print_operand): Likewise.
	* doc/extend.texi: Added XCValu documentation.
	* config/riscv/corev.def: New file.
	* config/riscv/corev.md: New file.

gcc/testsuite/ChangeLog:

	* lib/target-supports.exp: Added proc for the XCValu extension.
	* gcc.target/riscv/cv-alu-compile.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addrn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addun.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addurn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-clip.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-clipu.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subrn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subun.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-suburn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile.c: New test.
---
 gcc/common/config/riscv/riscv-common.cc       |   2 +
 gcc/config/riscv/constraints.md               |   7 +
 gcc/config/riscv/corev.def                    |  24 ++
 gcc/config/riscv/corev.md                     | 285 ++++++++++++++++++
 gcc/config/riscv/predicates.md                |   5 +
 gcc/config/riscv/riscv-builtins.cc            |   3 +
 gcc/config/riscv/riscv-ftypes.def             |   6 +
 gcc/config/riscv/riscv-opts.h                 |   2 +
 gcc/config/riscv/riscv.cc                     |   7 +
 gcc/doc/extend.texi                           |  94 ++++++
 .../gcc.target/riscv/cv-alu-compile.c         | 252 ++++++++++++++++
 .../riscv/cv-alu-fail-compile-addn.c          |  11 +
 .../riscv/cv-alu-fail-compile-addrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-addun.c         |  11 +
 .../riscv/cv-alu-fail-compile-addurn.c        |  11 +
 .../riscv/cv-alu-fail-compile-clip.c          |  11 +
 .../riscv/cv-alu-fail-compile-clipu.c         |  11 +
 .../riscv/cv-alu-fail-compile-subn.c          |  11 +
 .../riscv/cv-alu-fail-compile-subrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-subun.c         |  11 +
 .../riscv/cv-alu-fail-compile-suburn.c        |  11 +
 .../gcc.target/riscv/cv-alu-fail-compile.c    |  32 ++
 gcc/testsuite/lib/target-supports.exp         |  13 +
 23 files changed, 842 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c

diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 53e21fa4bce..e7c1a99fbd2 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -311,6 +311,7 @@ static const struct riscv_ext_version riscv_ext_version_table[] =
   {"svpbmt",  ISA_SPEC_CLASS_NONE, 1, 0},
 
   {"xcvmac", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xcvalu", ISA_SPEC_CLASS_NONE, 1, 0},
 
   {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1483,6 +1484,7 @@ 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},
+  {"xcvalu",        &gcc_options::x_riscv_xcv_flags, MASK_XCVALU},
 
   {"xtheadba",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBA},
   {"xtheadbb",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBB},
diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index 3f52bc76f67..33e43260fac 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -131,6 +131,13 @@
 (define_register_constraint "zmvr" "(TARGET_ZFA || TARGET_XTHEADFMV) ? GR_REGS : NO_REGS"
   "An integer register for  ZFA or XTheadFmv.")
 
+;; CORE-V Constraints
+(define_constraint "CVP2"
+  "Checking for CORE-V ALU clip if ival plus 1 is a power of 2"
+  (and (match_code "const_int")
+       (and (match_test "IN_RANGE (ival, 0, 1073741823)")
+            (match_test "exact_log2 (ival + 1) != -1"))))
+
 ;; Vector constraints.
 
 (define_register_constraint "vr" "TARGET_VECTOR ? V_REGS : NO_REGS"
diff --git a/gcc/config/riscv/corev.def b/gcc/config/riscv/corev.def
index a4e94680d8e..17580df3c41 100644
--- a/gcc/config/riscv/corev.def
+++ b/gcc/config/riscv/corev.def
@@ -17,3 +17,27 @@ RISCV_BUILTIN (cv_mac_macuRN,    "cv_mac_macuRN",     RISCV_BUILTIN_DIRECT, RISC
 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),
+
+// XCVALU
+RISCV_BUILTIN (cv_alu_slet,     "cv_alu_slet",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_sletu,    "cv_alu_sletu", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_USI_USI,   cvalu),
+RISCV_BUILTIN (cv_alu_min,      "cv_alu_min",   RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_minu,     "cv_alu_minu",  RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+RISCV_BUILTIN (cv_alu_max,      "cv_alu_max",   RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_maxu,     "cv_alu_maxu",  RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+
+RISCV_BUILTIN (cv_alu_exths,    "cv_alu_exths", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_HI,        cvalu),
+RISCV_BUILTIN (cv_alu_exthz,    "cv_alu_exthz", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_UHI,      cvalu),
+RISCV_BUILTIN (cv_alu_extbs,    "cv_alu_extbs", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_QI,        cvalu),
+RISCV_BUILTIN (cv_alu_extbz,    "cv_alu_extbz", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_UQI,      cvalu),
+
+RISCV_BUILTIN (cv_alu_clip,     "cv_alu_clip",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_clipu,    "cv_alu_clipu", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+RISCV_BUILTIN (cv_alu_addN,     "cv_alu_addN",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_adduN,    "cv_alu_adduN", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_addRN,    "cv_alu_addRN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_adduRN,   "cv_alu_adduRN",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_subN,     "cv_alu_subN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_subuN,    "cv_alu_subuN", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_subRN,    "cv_alu_subRN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_subuRN,   "cv_alu_subuRN",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
diff --git a/gcc/config/riscv/corev.md b/gcc/config/riscv/corev.md
index 59aeafe485f..30c8bcbe476 100644
--- a/gcc/config/riscv/corev.md
+++ b/gcc/config/riscv/corev.md
@@ -17,6 +17,27 @@
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.
 
+(define_c_enum "unspec" [
+
+  ;;CORE-V ALU
+  UNSPEC_CV_ALU_CLIP
+  UNSPEC_CV_ALU_CLIPR
+  UNSPEC_CV_ALU_CLIPU
+  UNSPEC_CV_ALU_CLIPUR
+  UNSPEC_CV_ALU_ADDN
+  UNSPEC_CV_ALU_ADDUN
+  UNSPEC_CV_ALU_ADDRN
+  UNSPEC_CV_ALU_ADDURN
+  UNSPEC_CV_ALU_SUBN
+  UNSPEC_CV_ALU_SUBUN
+  UNSPEC_CV_ALU_SUBRN
+  UNSPEC_CV_ALU_SUBURN
+  UNSPEC_CV_ALU_EXTHS
+  UNSPEC_CV_ALU_EXTHZ
+  UNSPEC_CV_ALU_EXTBS
+  UNSPEC_CV_ALU_EXTBZ
+])
+
 ;; XCVMAC extension.
 
 (define_insn "riscv_cv_mac_mac"
@@ -388,3 +409,267 @@
   "cv.machhsRN\t%0,%1,%2,%4"
   [(set_attr "type" "arith")
   (set_attr "mode" "SI")])
+
+;; XCVALU builtins
+
+(define_insn "riscv_cv_alu_slet"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (if_then_else
+      (gt:SI
+        (match_operand:SI 1 "register_operand" "r")
+        (match_operand:SI 2 "register_operand" "r"))
+      (const_int 0)
+      (const_int 1)))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.slet\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_sletu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (if_then_else
+      (gtu:SI
+        (match_operand:SI 1 "register_operand" "r")
+        (match_operand:SI 2 "register_operand" "r"))
+      (const_int 0)
+      (const_int 1)))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.sletu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_min"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (if_then_else
+      (gt:SI
+        (match_operand:SI 1 "register_operand" "r")
+        (match_operand:SI 2 "register_operand" "r"))
+      (match_dup:SI 2)
+      (match_dup:SI 1)))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.min\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_minu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (if_then_else
+      (gtu:SI
+        (match_operand:SI 1 "register_operand" "r")
+        (match_operand:SI 2 "register_operand" "r"))
+      (match_dup:SI 2)
+      (match_dup:SI 1)))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.minu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_max"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (if_then_else
+      (gt:SI
+        (match_operand:SI 1 "register_operand" "r")
+        (match_operand:SI 2 "register_operand" "r"))
+      (match_dup:SI 1)
+      (match_dup:SI 2)))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.max\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_maxu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (if_then_else
+      (gtu:SI
+        (match_operand:SI 1 "register_operand" "r")
+        (match_operand:SI 2 "register_operand" "r"))
+      (match_dup:SI 1)
+      (match_dup:SI 2)))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.maxu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_exths"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (unspec:SI [(match_operand:HI 1 "register_operand" "r")]
+    UNSPEC_CV_ALU_EXTHS))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.exths\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_exthz"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (unspec:SI [(match_operand:HI 1 "register_operand" "r")]
+    UNSPEC_CV_ALU_EXTHZ))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.exthz\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_extbs"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (unspec:SI [(match_operand:QI 1 "register_operand" "r")]
+    UNSPEC_CV_ALU_EXTBS))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.extbs\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_extbz"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (unspec:SI [(match_operand:QI 1 "register_operand" "r")]
+    UNSPEC_CV_ALU_EXTBZ))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.extbz\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_clip"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
+    UNSPEC_CV_ALU_CLIP))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.clip\t%0,%1,%X2
+  cv.clipr\t%0,%1,%2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_clipu"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
+    UNSPEC_CV_ALU_CLIPU))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.clipu\t%0,%1,%X2
+  cv.clipur\t%0,%1,%2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_addN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_ADDN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addN\t%0,%1,%2,%3
+  cv.addNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_adduN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+		(match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_ADDUN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.adduN\t%0,%1,%2,%3
+  cv.adduNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_addRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_ADDRN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addRN\t%0,%1,%2,%3
+  cv.addRNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_adduRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_ADDURN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.adduRN\t%0,%1,%2,%3
+  cv.adduRNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_SUBN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subN\t%0,%1,%2,%3
+  cv.subNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subuN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_SUBUN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subuN\t%0,%1,%2,%3
+  cv.subuNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_SUBRN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subRN\t%0,%1,%2,%3
+  cv.subRNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subuRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
+                (match_operand:SI 2 "register_operand" "r,r")
+                (match_operand:QI 3 "csr_operand" "K,r")]
+     UNSPEC_CV_ALU_SUBURN))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subuRN\t%0,%1,%2,%3
+  cv.subuRNr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 4bc7ff2c9d8..0c6926dceb5 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -387,6 +387,11 @@
 	return true;
 })
 
+;; CORE-V Predicates:
+(define_predicate "immediate_register_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_code "const_int")))
+
 ;; Predicates for the V extension.
 (define_special_predicate "vector_length_operand"
   (ior (match_operand 0 "pmode_register_operand")
diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc
index 1f733337b82..fc3976f3ba1 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -127,6 +127,7 @@ AVAIL (hint_pause, (!0))
 
 // CORE-V AVAIL
 AVAIL (cvmac, TARGET_XCVMAC && !TARGET_64BIT)
+AVAIL (cvalu, TARGET_XCVALU && !TARGET_64BIT)
 
 /* Construct a riscv_builtin_description from the given arguments.
 
@@ -163,6 +164,8 @@ AVAIL (cvmac, TARGET_XCVMAC && !TARGET_64BIT)
 #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_QI intQI_type_node
+#define RISCV_ATYPE_HI intHI_type_node
 #define RISCV_ATYPE_SI intSI_type_node
 #define RISCV_ATYPE_VOID_PTR ptr_type_node
 
diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def
index 430a4c2d673..0d1e4dd061e 100644
--- a/gcc/config/riscv/riscv-ftypes.def
+++ b/gcc/config/riscv/riscv-ftypes.def
@@ -32,6 +32,10 @@ DEF_RISCV_FTYPE (1, (VOID, USI))
 DEF_RISCV_FTYPE (1, (VOID, VOID_PTR))
 DEF_RISCV_FTYPE (1, (USI, USI))
 DEF_RISCV_FTYPE (1, (UDI, UDI))
+DEF_RISCV_FTYPE (1, (USI, UQI))
+DEF_RISCV_FTYPE (1, (USI, UHI))
+DEF_RISCV_FTYPE (1, (SI, QI))
+DEF_RISCV_FTYPE (1, (SI, HI))
 DEF_RISCV_FTYPE (2, (USI, UQI, UQI))
 DEF_RISCV_FTYPE (2, (USI, UHI, UHI))
 DEF_RISCV_FTYPE (2, (USI, USI, USI))
@@ -40,6 +44,8 @@ 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 (2, (SI, USI, USI))
+DEF_RISCV_FTYPE (2, (SI, SI, SI))
 DEF_RISCV_FTYPE (3, (USI, USI, USI, UQI))
 DEF_RISCV_FTYPE (3, (USI, USI, USI, USI))
 DEF_RISCV_FTYPE (3, (SI, SI, SI, UQI))
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 8b0aa1d1b41..ec929bc5fe9 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -296,6 +296,7 @@ enum riscv_entity
    : 32 << (__builtin_popcount (riscv_zvl_flags) - 1))
 
 #define MASK_XCVMAC    (1 <<  0)
+#define MASK_XCVALU    (1 <<  1)
 
 #define MASK_XTHEADBA      (1 << 0)
 #define MASK_XTHEADBB      (1 << 1)
@@ -312,6 +313,7 @@ enum riscv_entity
 
 
 #define TARGET_XCVMAC    ((riscv_xcv_flags & MASK_XCVMAC) != 0)
+#define TARGET_XCVALU    ((riscv_xcv_flags & MASK_XCVALU) != 0)
 
 #define TARGET_XTHEADBA      ((riscv_xthead_subext & MASK_XTHEADBA) != 0)
 #define TARGET_XTHEADBB      ((riscv_xthead_subext & MASK_XTHEADBB) != 0)
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f1b721d54d1..ff73f2ba6d9 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -5633,6 +5633,13 @@ riscv_print_operand (FILE *file, rtx op, int letter)
 	output_addr_const (file, newop);
 	break;
       }
+    case 'X':
+      {
+        int ival = INTVAL (op) + 1;
+        rtx newop = GEN_INT (ctz_hwi (ival) + 1);
+        output_addr_const (file, newop);
+	break;
+      }
     default:
       switch (code)
 	{
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index f6753de0028..e889b18b643 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -21731,6 +21731,100 @@ Generates the @code{cv.macsRN} machine instruction.
 Generates the @code{cv.machhsRN} machine instruction.
 @end deftypefn
 
+These built-in functions are available for the CORE-V ALU 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-miscellaneous-alu-builtins-xcvalu}
+
+@deftypefn {Built-in Function} {int} __builtin_riscv_cv_alu_slet (int32_t, int32_t)
+Generated assembler @code{cv.slet}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int} __builtin_riscv_cv_alu_sletu (uint32_t, uint32_t)
+Generated assembler @code{cv.sletu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_min (int32_t, int32_t)
+Generated assembler @code{cv.min}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_minu (uint32_t, uint32_t)
+Generated assembler @code{cv.minu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_max (int32_t, int32_t)
+Generated assembler @code{cv.max}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_tnt} __builtin_riscv_cv_alu_maxu (uint32_t, uint32_t)
+Generated assembler @code{cv.maxu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_exths (int16_t)
+Generated assembler @code{cv.exths}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_exthz (uint16_t)
+Generated assembler @code{cv.exthz}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_extbs (int8_t)
+Generated assembler @code{cv.extbs}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_extbz (uint8_t)
+Generated assembler @code{cv.extbz}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_clip (int32_t, uint32_t)
+Generated assembler @code{cv.clip} if the uint32_t operand is a constant and an exact power of 2.
+Generated assembler @code{cv.clipr} if  the it is a register.
+@end deftypefn
+ 
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_clipu (uint32_t, uint32_t)
+Generated assembler @code{cv.clipu} if the uint32_t operand is a constant and an exact power of 2.
+Generated assembler @code{cv.clipur} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_addN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.addN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.addNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_adduN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.adduN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.adduNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_addRN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.addRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.addRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_adduRN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.adduRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.adduRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_subN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.subN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_subuN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.subuN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subuNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_subRN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.subRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_subuRN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.subuRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subuRNr} if  the it is a register.
+@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-alu-compile.c b/gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
new file mode 100644
index 00000000000..4ce3a1b83b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
@@ -0,0 +1,252 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+#include <stdint.h>
+
+extern int d;
+extern int e;
+extern int f;
+
+void
+foo0(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, 0);
+  e = __builtin_riscv_cv_alu_addN (a, b, 7);
+  f = __builtin_riscv_cv_alu_addN (a, b, 31);
+}
+
+void
+foo1(int a, int b, int c)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, c);
+}
+
+void
+foo2(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_addRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_addRN (a, b, 31);
+}
+
+int
+foo3(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_addRN (a, b, c);
+}
+
+void
+foo4(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduN (a, b, 0);
+  e = __builtin_riscv_cv_alu_adduN (a, b, 7);
+  f = __builtin_riscv_cv_alu_adduN (a, b, 31);
+}
+
+int
+foo5(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_adduN (a, b, c);
+}
+
+void
+foo6(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_adduRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_adduRN (a, b, 31);
+}
+
+int
+foo7(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_adduRN (a, b, c);
+}
+
+int
+foo8(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clip (a, 15);
+}
+
+int
+foo9(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clip (a, 10);
+}
+
+int
+foo10(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clipu (a, 15);
+}
+
+int
+foo11(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clipu (a, 10);
+}
+
+int
+foo12(int a)
+{
+  return __builtin_riscv_cv_alu_extbs (a);
+}
+
+int
+foo13(int a)
+{
+  return __builtin_riscv_cv_alu_extbz (a);
+}
+
+int
+foo14(int b)
+{
+  return __builtin_riscv_cv_alu_exths (b);
+}
+
+int
+foo15(int a)
+{
+  return __builtin_riscv_cv_alu_exthz (a);
+}
+
+int
+foo16(int a, int b)
+{
+  return __builtin_riscv_cv_alu_max (a, b);
+}
+
+int
+foo17(int a, int b)
+{
+  return __builtin_riscv_cv_alu_maxu (a, b);
+}
+
+int
+foo18(int a, int b)
+{
+  return __builtin_riscv_cv_alu_min (a, b);
+}
+
+int
+foo19(int a, int b)
+{
+  return __builtin_riscv_cv_alu_minu (a, b);
+}
+
+int
+foo20(int a, int b)
+{
+  return __builtin_riscv_cv_alu_slet (a, b);
+}
+
+int
+foo21(unsigned int a, unsigned int b)
+{
+  return __builtin_riscv_cv_alu_sletu (a, b);
+}
+
+void
+foo22(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subN (a, b, 31);
+}
+
+int
+foo23(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subN (a, b, c);
+}
+
+void
+foo24(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subRN (a, b, 31);
+}
+
+int
+foo25(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subRN (a, b, c);
+}
+
+void
+foo26(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subuN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subuN (a, b, 31);
+}
+
+int
+foo27(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subuN (a, b, c);
+}
+
+void
+foo28(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subuRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subuRN (a, b, 31);
+}
+
+int
+foo29(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subuRN (a, b, c);
+}
+
+/* { dg-final { scan-assembler-times "cv\.addN\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\.addN\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\.addN\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\\.addNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addRN\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\.addRN\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\.addRN\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\\.addRNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.adduN\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\.adduN\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\.adduN\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\\.adduNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.adduRN\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\.adduRN\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\.adduRN\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\\.adduRNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.clip\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),5" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.clipr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.clipu\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),5" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.clipur\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.extbs\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.extbz\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.exths\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.exthz\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.max\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.maxu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.min\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.minu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.slet\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.sletu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subN\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\.subN\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\.subN\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\\.subNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subRN\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\.subRN\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\.subRN\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\\.subRNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subuN\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\.subuN\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\.subuN\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\\.subuNr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subuRN\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\.subuRN\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\.subuRN\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\\.subuRNr\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
new file mode 100644
index 00000000000..aa8610f4c2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
new file mode 100644
index 00000000000..12371b2c641
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
new file mode 100644
index 00000000000..3faad6c73c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
new file mode 100644
index 00000000000..39dc575b68e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
new file mode 100644
index 00000000000..a5ee231c74d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_clip (a, 4294967296); /* { dg-warning "overflow in conversion from \'long long int\' to \'int\' changes value from \'4294967296\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
new file mode 100644
index 00000000000..1ee11d2f600
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_clipu (a, 4294967296); /* { dg-warning "unsigned conversion from \'long long int\' to \'unsigned int\' changes value from \'4294967296\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
new file mode 100644
index 00000000000..91d6bd56672
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
new file mode 100644
index 00000000000..3c7e4ae63d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
new file mode 100644
index 00000000000..46218ea4451
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
new file mode 100644
index 00000000000..f20378dd839
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
new file mode 100644
index 00000000000..bbdb2d58c3f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i -mabi=ilp32" } */
+
+extern int d;
+
+int
+foo(int a, int b, int c)
+{
+    d += __builtin_riscv_cv_alu_slet (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_sletu (a, b);  /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_addN (a, b, 31);  /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_addRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_adduN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_adduRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_clip (a, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_clipu (a, 35); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_extbs (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_extbz (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_exths (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_exthz (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_min (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_minu (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_max (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_maxu (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subuN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subuRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+
+    return d;
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 45baf112983..f376fd1340c 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -12669,6 +12669,19 @@ proc check_effective_target_cv_mac { } {
     } "-march=rv32i_xcvmac" ]
 }
 
+# Return 1 if the CORE-V ALU extension is available.
+proc check_effective_target_cv_alu { } {
+    if { !([istarget riscv*-*-*]) } {
+         return 0
+     }
+    return [check_no_compiler_messages cv_alu object {
+        void foo (void)
+        {
+          asm ("cv.addn t0, t1, t2, 0");
+        }
+    } "-march=rv32i_xcvalu" ]
+}
+
 # Appends necessary Python flags to extra-tool-flags if Python.h is supported.
 # Otherwise, modifies dg-do-what.
 proc dg-require-python-h { args } {
-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/2] RISC-V: Add support for XCValu extension in CV32E40P
  2023-09-19 15:07 ` [PATCH 2/2] RISC-V: Add support for XCValu " Mary Bennett
@ 2023-09-23  9:04   ` Kito Cheng
  0 siblings, 0 replies; 15+ messages in thread
From: Kito Cheng @ 2023-09-23  9:04 UTC (permalink / raw)
  To: Mary Bennett; +Cc: gcc-patches

Hi Mary:

Several inline comments, mostly are related to the RTX pattern. I
guess we don't really need those unspec except clip*.

> diff --git a/gcc/config/riscv/corev.md b/gcc/config/riscv/corev.md
> index 59aeafe485f..30c8bcbe476 100644
> --- a/gcc/config/riscv/corev.md
> +++ b/gcc/config/riscv/corev.md
> @@ -17,6 +17,27 @@
>  ;; along with GCC; see the file COPYING3.  If not see
>  ;; <http://www.gnu.org/licenses/>.
>
> +(define_c_enum "unspec" [
> +
> +  ;;CORE-V ALU
> +  UNSPEC_CV_ALU_CLIP
> +  UNSPEC_CV_ALU_CLIPR
> +  UNSPEC_CV_ALU_CLIPU
> +  UNSPEC_CV_ALU_CLIPUR
> +  UNSPEC_CV_ALU_ADDN
> +  UNSPEC_CV_ALU_ADDUN
> +  UNSPEC_CV_ALU_ADDRN
> +  UNSPEC_CV_ALU_ADDURN
> +  UNSPEC_CV_ALU_SUBN
> +  UNSPEC_CV_ALU_SUBUN
> +  UNSPEC_CV_ALU_SUBRN
> +  UNSPEC_CV_ALU_SUBURN
> +  UNSPEC_CV_ALU_EXTHS
> +  UNSPEC_CV_ALU_EXTHZ
> +  UNSPEC_CV_ALU_EXTBS
> +  UNSPEC_CV_ALU_EXTBZ
> +])
> +
>  ;; XCVMAC extension.
>
>  (define_insn "riscv_cv_mac_mac"
> @@ -388,3 +409,267 @@
>    "cv.machhsRN\t%0,%1,%2,%4"
>    [(set_attr "type" "arith")
>    (set_attr "mode" "SI")])
> +
> +;; XCVALU builtins
> +
> +(define_insn "riscv_cv_alu_slet"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +    (if_then_else
> +      (gt:SI
> +        (match_operand:SI 1 "register_operand" "r")
> +        (match_operand:SI 2 "register_operand" "r"))
> +      (const_int 0)
> +      (const_int 1)))]

Maybe just something like that? slt instruction using similar pattern like that.
(set (match_operand:SI 0 "register_operand" "=r")
       (gt:SI
         (match_operand:SI 1 "register_operand" "r")
         (match_operand:SI 2 "register_operand" "r")))


> +
> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.slet\t%0, %1, %2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_sletu"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +    (if_then_else
> +      (gtu:SI
> +        (match_operand:SI 1 "register_operand" "r")
> +        (match_operand:SI 2 "register_operand" "r"))
> +      (const_int 0)
> +      (const_int 1)))]

Same comment as riscv_cv_alu_slet.

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.sletu\t%0, %1, %2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_min"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +    (if_then_else
> +      (gt:SI
> +        (match_operand:SI 1 "register_operand" "r")
> +        (match_operand:SI 2 "register_operand" "r"))
> +      (match_dup:SI 2)
> +      (match_dup:SI 1)))]

Maybe something like that?

(set (match_operand:SI 0 "register_operand" "=r")
   (min
     (match_operand:SI 1 "register_operand" "r")
     (match_operand:SI 2 "register_operand" "r")))

> +
> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.min\t%0, %1, %2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_minu"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +    (if_then_else
> +      (gtu:SI
> +        (match_operand:SI 1 "register_operand" "r")
> +        (match_operand:SI 2 "register_operand" "r"))
> +      (match_dup:SI 2)
> +      (match_dup:SI 1)))]


(set (match_operand:SI 0 "register_operand" "=r")
   (minu
     (match_operand:SI 1 "register_operand" "r")
     (match_operand:SI 2 "register_operand" "r")))


> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.minu\t%0, %1, %2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_max"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +    (if_then_else
> +      (gt:SI
> +        (match_operand:SI 1 "register_operand" "r")
> +        (match_operand:SI 2 "register_operand" "r"))
> +      (match_dup:SI 1)
> +      (match_dup:SI 2)))]

(set (match_operand:SI 0 "register_operand" "=r")
   (max
     (match_operand:SI 1 "register_operand" "r")
     (match_operand:SI 2 "register_operand" "r")))


> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.max\t%0, %1, %2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_maxu"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +    (if_then_else
> +      (gtu:SI
> +        (match_operand:SI 1 "register_operand" "r")
> +        (match_operand:SI 2 "register_operand" "r"))


(set (match_operand:SI 0 "register_operand" "=r")
   (maxu
     (match_operand:SI 1 "register_operand" "r")
     (match_operand:SI 2 "register_operand" "r")))


> +      (match_dup:SI 1)
> +      (match_dup:SI 2)))]
> +
> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.maxu\t%0, %1, %2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_exths"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +   (unspec:SI [(match_operand:HI 1 "register_operand" "r")]
> +    UNSPEC_CV_ALU_EXTHS))]

It's sign-extension from HI to SI?

if so that should just using sign_extend rather than unspec

  [(set (match_operand:SI 0 "register_operand" "=r")
        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r")))]


> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.exths\t%0, %1"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_exthz"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +   (unspec:SI [(match_operand:HI 1 "register_operand" "r")]
> +    UNSPEC_CV_ALU_EXTHZ))]

same comment as riscv_cv_alu_exths but zero_extend


> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.exthz\t%0, %1"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_extbs"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +   (unspec:SI [(match_operand:QI 1 "register_operand" "r")]
> +    UNSPEC_CV_ALU_EXTBS))]
> +

same comment as riscv_cv_alu_exths with QI

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.extbs\t%0, %1"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_extbz"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +   (unspec:SI [(match_operand:QI 1 "register_operand" "r")]
> +    UNSPEC_CV_ALU_EXTBZ))]

same comment as riscv_cv_alu_exths with QI and zero_extend

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "cv.extbz\t%0, %1"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_clip"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
> +               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
> +    UNSPEC_CV_ALU_CLIP))]
> +
> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.clip\t%0,%1,%X2
> +  cv.clipr\t%0,%1,%2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_clipu"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
> +               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
> +    UNSPEC_CV_ALU_CLIPU))]
> +
> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.clipu\t%0,%1,%X2
> +  cv.clipur\t%0,%1,%2"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_addN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_ADDN))]

I think this should be able to using generic RTL rather than unspec to
represent that?

e.g.
(set (match_operand) (ashiftrt (plus (match_operand) (match_operand))
(match_operand)))

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.addN\t%0,%1,%2,%3
> +  cv.addNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_adduN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +               (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_ADDUN))]
> +

same comment as riscv_cv_alu_addN but lshiftrt

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.adduN\t%0,%1,%2,%3
> +  cv.adduNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_addRN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_ADDRN))]

same comment as riscv_cv_alu_addN but few more complicated pattern.

> +
> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.addRN\t%0,%1,%2,%3
> +  cv.addRNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_adduRN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_ADDURN))]

same comment as riscv_cv_alu_addN but few more complicated pattern.

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.adduRN\t%0,%1,%2,%3
> +  cv.adduRNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_subN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_SUBN))]

same comment as riscv_cv_alu_addN but few more complicated pattern.

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.subN\t%0,%1,%2,%3
> +  cv.subNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_subuN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_SUBUN))]

same comment as riscv_cv_alu_addN but few more complicated pattern.

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.subuN\t%0,%1,%2,%3
> +  cv.subuNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_subRN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_SUBRN))]

same comment as riscv_cv_alu_addN but few more complicated pattern.

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.subRN\t%0,%1,%2,%3
> +  cv.subRNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])
> +
> +(define_insn "riscv_cv_alu_subuRN"
> +  [(set (match_operand:SI 0 "register_operand" "=r,r")
> +    (unspec:SI [(match_operand:SI 1 "register_operand" "r,0")
> +                (match_operand:SI 2 "register_operand" "r,r")
> +                (match_operand:QI 3 "csr_operand" "K,r")]
> +     UNSPEC_CV_ALU_SUBURN))]

same comment as riscv_cv_alu_addN but few more complicated pattern.

> +  "TARGET_XCVALU && !TARGET_64BIT"
> +  "@
> +  cv.subuRN\t%0,%1,%2,%3
> +  cv.subuRNr\t%0,%2,%3"
> +  [(set_attr "type" "arith")
> +  (set_attr "mode" "SI")])

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions
  2023-09-19 15:07 [PATCH 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
  2023-09-19 15:07 ` [PATCH 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
  2023-09-19 15:07 ` [PATCH 2/2] RISC-V: Add support for XCValu " Mary Bennett
@ 2023-09-27 12:26 ` Mary Bennett
  2023-09-27 12:26   ` [PATCH v2 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
                     ` (2 more replies)
  2 siblings, 3 replies; 15+ messages in thread
From: Mary Bennett @ 2023-09-27 12:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: mary.bennett, kito.cheng

This patch series presents the comprehensive implementation of the MAC and ALU
extension for CORE-V.

Tested with riscv-gnu-toolchain on binutils, ld, gas and gcc testsuites to
ensure its correctness and compatibility with the existing codebase.
However, your input, reviews, and suggestions are invaluable in making this
extension even more robust.

The CORE-V builtins are described in the specification [1] and work can be
found in the OpenHW group's Github repository [2].

[1] github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md

[2] github.com/openhwgroup/corev-gcc

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>

  RISC-V: Add support for XCValu extension in CV32E40P
  RISC-V: Add support for XCVmac extension in CV32E40P

 gcc/common/config/riscv/riscv-common.cc       |   6 +
 gcc/config/riscv/constraints.md               |   7 +
 gcc/config/riscv/corev.def                    |  43 ++
 gcc/config/riscv/corev.md                     | 693 ++++++++++++++++++
 gcc/config/riscv/predicates.md                |   5 +
 gcc/config/riscv/riscv-builtins.cc            |  13 +
 gcc/config/riscv/riscv-ftypes.def             |  11 +
 gcc/config/riscv/riscv-opts.h                 |   7 +
 gcc/config/riscv/riscv.cc                     |   7 +
 gcc/config/riscv/riscv.md                     |   1 +
 gcc/config/riscv/riscv.opt                    |   3 +
 gcc/doc/extend.texi                           | 174 +++++
 .../gcc.target/riscv/cv-alu-compile.c         | 252 +++++++
 .../riscv/cv-alu-fail-compile-addn.c          |  11 +
 .../riscv/cv-alu-fail-compile-addrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-addun.c         |  11 +
 .../riscv/cv-alu-fail-compile-addurn.c        |  11 +
 .../riscv/cv-alu-fail-compile-clip.c          |  11 +
 .../riscv/cv-alu-fail-compile-clipu.c         |  11 +
 .../riscv/cv-alu-fail-compile-subn.c          |  11 +
 .../riscv/cv-alu-fail-compile-subrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-subun.c         |  11 +
 .../riscv/cv-alu-fail-compile-suburn.c        |  11 +
 .../gcc.target/riscv/cv-alu-fail-compile.c    |  32 +
 .../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         |  26 +
 45 files changed, 2040 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-alu-compile.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
 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

-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 1/2] RISC-V: Add support for XCVmac extension in CV32E40P
  2023-09-27 12:26 ` [PATCH v2 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
@ 2023-09-27 12:26   ` Mary Bennett
  2023-09-27 12:26   ` [PATCH v2 2/2] RISC-V: Add support for XCValu " Mary Bennett
  2023-09-30 12:00   ` [PATCH v3 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
  2 siblings, 0 replies; 15+ messages in thread
From: Mary Bennett @ 2023-09-27 12:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: mary.bennett, kito.cheng

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

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..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-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..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 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 } {
-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2 2/2] RISC-V: Add support for XCValu extension in CV32E40P
  2023-09-27 12:26 ` [PATCH v2 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
  2023-09-27 12:26   ` [PATCH v2 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
@ 2023-09-27 12:26   ` Mary Bennett
  2023-09-30 12:00   ` [PATCH v3 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
  2 siblings, 0 replies; 15+ messages in thread
From: Mary Bennett @ 2023-09-27 12:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: mary.bennett, kito.cheng

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 the XCValu
	extension.
	* config/riscv/constraints.md: Added builtins for the XCValu
	extension.
	* config/riscv/predicates.md (immediate_register_operand):
	Likewise.
	* config/riscv/corev.def: Likewise.
	* config/riscv/corev.md: Likewise.
	* config/riscv/riscv-builtins.cc (AVAIL): Likewise.
	  (RISCV_ATYPE_UHI): Likewise.
	* config/riscv/riscv-ftypes.def: Likewise.
	* config/riscv/riscv-opts.h: Likewise.
	* config/riscv/riscv.opt: Likewise.
	* config/riscv/riscv.cc (riscv_print_operand): Likewise.
	* doc/extend.texi: Added XCValu documentation.

gcc/testsuite/ChangeLog:

	* lib/target-supports.exp: Added proc for the XCValu extension.
	* gcc.target/riscv/cv-alu-compile.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addrn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addun.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addurn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-clip.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-clipu.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subrn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subun.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-suburn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile.c: New test.
---
 gcc/common/config/riscv/riscv-common.cc       |   2 +
 gcc/config/riscv/constraints.md               |   7 +
 gcc/config/riscv/corev.def                    |  24 ++
 gcc/config/riscv/corev.md                     | 303 ++++++++++++++++++
 gcc/config/riscv/predicates.md                |   5 +
 gcc/config/riscv/riscv-builtins.cc            |   3 +
 gcc/config/riscv/riscv-ftypes.def             |   6 +
 gcc/config/riscv/riscv-opts.h                 |   2 +
 gcc/config/riscv/riscv.cc                     |   7 +
 gcc/doc/extend.texi                           |  94 ++++++
 .../gcc.target/riscv/cv-alu-compile.c         | 252 +++++++++++++++
 .../riscv/cv-alu-fail-compile-addn.c          |  11 +
 .../riscv/cv-alu-fail-compile-addrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-addun.c         |  11 +
 .../riscv/cv-alu-fail-compile-addurn.c        |  11 +
 .../riscv/cv-alu-fail-compile-clip.c          |  11 +
 .../riscv/cv-alu-fail-compile-clipu.c         |  11 +
 .../riscv/cv-alu-fail-compile-subn.c          |  11 +
 .../riscv/cv-alu-fail-compile-subrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-subun.c         |  11 +
 .../riscv/cv-alu-fail-compile-suburn.c        |  11 +
 .../gcc.target/riscv/cv-alu-fail-compile.c    |  32 ++
 gcc/testsuite/lib/target-supports.exp         |  13 +
 23 files changed, 860 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c

diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 53e21fa4bce..e7c1a99fbd2 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -311,6 +311,7 @@ static const struct riscv_ext_version riscv_ext_version_table[] =
   {"svpbmt",  ISA_SPEC_CLASS_NONE, 1, 0},
 
   {"xcvmac", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xcvalu", ISA_SPEC_CLASS_NONE, 1, 0},
 
   {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1483,6 +1484,7 @@ 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},
+  {"xcvalu",        &gcc_options::x_riscv_xcv_flags, MASK_XCVALU},
 
   {"xtheadba",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBA},
   {"xtheadbb",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBB},
diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index 3f52bc76f67..33e43260fac 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -131,6 +131,13 @@
 (define_register_constraint "zmvr" "(TARGET_ZFA || TARGET_XTHEADFMV) ? GR_REGS : NO_REGS"
   "An integer register for  ZFA or XTheadFmv.")
 
+;; CORE-V Constraints
+(define_constraint "CVP2"
+  "Checking for CORE-V ALU clip if ival plus 1 is a power of 2"
+  (and (match_code "const_int")
+       (and (match_test "IN_RANGE (ival, 0, 1073741823)")
+            (match_test "exact_log2 (ival + 1) != -1"))))
+
 ;; Vector constraints.
 
 (define_register_constraint "vr" "TARGET_VECTOR ? V_REGS : NO_REGS"
diff --git a/gcc/config/riscv/corev.def b/gcc/config/riscv/corev.def
index a4e94680d8e..17580df3c41 100644
--- a/gcc/config/riscv/corev.def
+++ b/gcc/config/riscv/corev.def
@@ -17,3 +17,27 @@ RISCV_BUILTIN (cv_mac_macuRN,    "cv_mac_macuRN",     RISCV_BUILTIN_DIRECT, RISC
 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),
+
+// XCVALU
+RISCV_BUILTIN (cv_alu_slet,     "cv_alu_slet",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_sletu,    "cv_alu_sletu", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_USI_USI,   cvalu),
+RISCV_BUILTIN (cv_alu_min,      "cv_alu_min",   RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_minu,     "cv_alu_minu",  RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+RISCV_BUILTIN (cv_alu_max,      "cv_alu_max",   RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_maxu,     "cv_alu_maxu",  RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+
+RISCV_BUILTIN (cv_alu_exths,    "cv_alu_exths", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_HI,        cvalu),
+RISCV_BUILTIN (cv_alu_exthz,    "cv_alu_exthz", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_UHI,      cvalu),
+RISCV_BUILTIN (cv_alu_extbs,    "cv_alu_extbs", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_QI,        cvalu),
+RISCV_BUILTIN (cv_alu_extbz,    "cv_alu_extbz", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_UQI,      cvalu),
+
+RISCV_BUILTIN (cv_alu_clip,     "cv_alu_clip",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_clipu,    "cv_alu_clipu", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+RISCV_BUILTIN (cv_alu_addN,     "cv_alu_addN",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_adduN,    "cv_alu_adduN", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_addRN,    "cv_alu_addRN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_adduRN,   "cv_alu_adduRN",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_subN,     "cv_alu_subN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_subuN,    "cv_alu_subuN", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_subRN,    "cv_alu_subRN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_subuRN,   "cv_alu_subuRN",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
diff --git a/gcc/config/riscv/corev.md b/gcc/config/riscv/corev.md
index 65ce09ea6eb..1350bd4b81e 100644
--- a/gcc/config/riscv/corev.md
+++ b/gcc/config/riscv/corev.md
@@ -17,6 +17,15 @@
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.
 
+(define_c_enum "unspec" [
+
+  ;;CORE-V ALU
+  UNSPEC_CV_ALU_CLIP
+  UNSPEC_CV_ALU_CLIPR
+  UNSPEC_CV_ALU_CLIPU
+  UNSPEC_CV_ALU_CLIPUR
+])
+
 ;; XCVMAC extension.
 
 (define_insn "riscv_cv_mac_mac"
@@ -388,3 +397,297 @@
   "cv.machhsrn\t%0,%1,%2,%4"
   [(set_attr "type" "arith")
   (set_attr "mode" "SI")])
+
+;; XCVALU builtins
+
+(define_insn "riscv_cv_alu_slet"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (le:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.sle\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_sletu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (leu:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.sleu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_min"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (smin:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.min\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_minu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (umin:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.minu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_max"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (smax:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.max\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_maxu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (umax:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.maxu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_exths"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (sign_extend:SI
+     (truncate:HI
+       (match_operand:HI 1 "register_operand" "r"))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.exths\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_exthz"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (zero_extend:SI
+     (truncate:HI
+       (match_operand:HI 1 "register_operand" "r"))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.exthz\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_extbs"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (sign_extend:SI
+     (truncate:QI
+       (match_operand:QI 1 "register_operand" "r"))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.extbs\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_extbz"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (zero_extend:SI
+     (truncate:QI
+   (match_operand:QI 1 "register_operand" "r"))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.extbz\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_clip"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
+    UNSPEC_CV_ALU_CLIP))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.clip\t%0,%1,%X2
+  cv.clipr\t%0,%1,%2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_clipu"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
+    UNSPEC_CV_ALU_CLIPU))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.clipu\t%0,%1,%X2
+  cv.clipur\t%0,%1,%2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_addN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (ashiftrt:SI
+      (plus:SI
+        (match_operand:SI 1 "register_operand" "r,0")
+        (match_operand:SI 2 "register_operand" "r,r"))
+      (and:SI (match_operand:QI 3 "csr_operand" "K,r")
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addn\t%0,%1,%2,%3
+  cv.addnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_adduN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (lshiftrt:SI
+      (plus:SI
+        (match_operand:SI 1 "register_operand" "r,0")
+        (match_operand:SI 2 "register_operand" "r,r"))
+      (and:SI (match_operand:QI 3 "csr_operand" "K,r")
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addun\t%0,%1,%2,%3
+  cv.addunr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_addRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (ashiftrt:SI
+      (plus:SI
+        (plus:SI
+          (match_operand:SI 1 "register_operand" "r,0")
+          (match_operand:SI 2 "register_operand" "r,r"))
+        (if_then_else (eq (match_operand:QI 3 "csr_operand" "K,r")
+                          (const_int 0))
+          (const_int 1)
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))))
+      (and:SI (match_dup 3)
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addrn\t%0,%1,%2,%3
+  cv.addrnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_adduRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (lshiftrt:SI
+      (plus:SI
+        (plus:SI
+          (match_operand:SI 1 "register_operand" "r,0")
+          (match_operand:SI 2 "register_operand" "r,r"))
+        (if_then_else (eq (match_operand:QI 3 "csr_operand" "K,r")
+                          (const_int 0))
+          (const_int 1)
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))))
+      (and:SI (match_dup 3)
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addurn\t%0,%1,%2,%3
+  cv.addurnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (ashiftrt:SI
+      (minus:SI
+        (match_operand:SI 1 "register_operand" "r,0")
+        (match_operand:SI 2 "register_operand" "r,r"))
+      (and:SI (match_operand:QI 3 "csr_operand" "K,r")
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subn\t%0,%1,%2,%3
+  cv.subnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subuN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (lshiftrt:SI
+      (minus:SI
+        (match_operand:SI 1 "register_operand" "r,0")
+        (match_operand:SI 2 "register_operand" "r,r"))
+      (and:SI (match_operand:QI 3 "csr_operand" "K,r")
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subun\t%0,%1,%2,%3
+  cv.subunr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (ashiftrt:SI
+      (plus:SI
+        (minus:SI
+          (match_operand:SI 1 "register_operand" "r,0")
+          (match_operand:SI 2 "register_operand" "r,r"))
+        (if_then_else (eq (match_operand:QI 3 "csr_operand" "K,r")
+                          (const_int 0))
+          (const_int 1)
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))))
+      (and:SI (match_dup 3)
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subrn\t%0,%1,%2,%3
+  cv.subrnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subuRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (lshiftrt:SI
+      (plus:SI
+        (minus:SI
+          (match_operand:SI 1 "register_operand" "r,0")
+          (match_operand:SI 2 "register_operand" "r,r"))
+        (if_then_else (eq (match_operand:QI 3 "csr_operand" "K,r")
+                          (const_int 0))
+          (const_int 1)
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))))
+      (and:SI (match_dup 3)
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.suburn\t%0,%1,%2,%3
+  cv.suburnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 4bc7ff2c9d8..0c6926dceb5 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -387,6 +387,11 @@
 	return true;
 })
 
+;; CORE-V Predicates:
+(define_predicate "immediate_register_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_code "const_int")))
+
 ;; Predicates for the V extension.
 (define_special_predicate "vector_length_operand"
   (ior (match_operand 0 "pmode_register_operand")
diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc
index 1f733337b82..fc3976f3ba1 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -127,6 +127,7 @@ AVAIL (hint_pause, (!0))
 
 // CORE-V AVAIL
 AVAIL (cvmac, TARGET_XCVMAC && !TARGET_64BIT)
+AVAIL (cvalu, TARGET_XCVALU && !TARGET_64BIT)
 
 /* Construct a riscv_builtin_description from the given arguments.
 
@@ -163,6 +164,8 @@ AVAIL (cvmac, TARGET_XCVMAC && !TARGET_64BIT)
 #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_QI intQI_type_node
+#define RISCV_ATYPE_HI intHI_type_node
 #define RISCV_ATYPE_SI intSI_type_node
 #define RISCV_ATYPE_VOID_PTR ptr_type_node
 
diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def
index 430a4c2d673..0d1e4dd061e 100644
--- a/gcc/config/riscv/riscv-ftypes.def
+++ b/gcc/config/riscv/riscv-ftypes.def
@@ -32,6 +32,10 @@ DEF_RISCV_FTYPE (1, (VOID, USI))
 DEF_RISCV_FTYPE (1, (VOID, VOID_PTR))
 DEF_RISCV_FTYPE (1, (USI, USI))
 DEF_RISCV_FTYPE (1, (UDI, UDI))
+DEF_RISCV_FTYPE (1, (USI, UQI))
+DEF_RISCV_FTYPE (1, (USI, UHI))
+DEF_RISCV_FTYPE (1, (SI, QI))
+DEF_RISCV_FTYPE (1, (SI, HI))
 DEF_RISCV_FTYPE (2, (USI, UQI, UQI))
 DEF_RISCV_FTYPE (2, (USI, UHI, UHI))
 DEF_RISCV_FTYPE (2, (USI, USI, USI))
@@ -40,6 +44,8 @@ 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 (2, (SI, USI, USI))
+DEF_RISCV_FTYPE (2, (SI, SI, SI))
 DEF_RISCV_FTYPE (3, (USI, USI, USI, UQI))
 DEF_RISCV_FTYPE (3, (USI, USI, USI, USI))
 DEF_RISCV_FTYPE (3, (SI, SI, SI, UQI))
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 8b0aa1d1b41..ec929bc5fe9 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -296,6 +296,7 @@ enum riscv_entity
    : 32 << (__builtin_popcount (riscv_zvl_flags) - 1))
 
 #define MASK_XCVMAC    (1 <<  0)
+#define MASK_XCVALU    (1 <<  1)
 
 #define MASK_XTHEADBA      (1 << 0)
 #define MASK_XTHEADBB      (1 << 1)
@@ -312,6 +313,7 @@ enum riscv_entity
 
 
 #define TARGET_XCVMAC    ((riscv_xcv_flags & MASK_XCVMAC) != 0)
+#define TARGET_XCVALU    ((riscv_xcv_flags & MASK_XCVALU) != 0)
 
 #define TARGET_XTHEADBA      ((riscv_xthead_subext & MASK_XTHEADBA) != 0)
 #define TARGET_XTHEADBB      ((riscv_xthead_subext & MASK_XTHEADBB) != 0)
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f1b721d54d1..88e6ccce391 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -5633,6 +5633,13 @@ riscv_print_operand (FILE *file, rtx op, int letter)
 	output_addr_const (file, newop);
 	break;
       }
+    case 'X':
+      {
+	int ival = INTVAL (op) + 1;
+	rtx newop = GEN_INT (ctz_hwi (ival) + 1);
+	output_addr_const (file, newop);
+	break;
+      }
     default:
       switch (code)
 	{
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index f6753de0028..423c1a7fb38 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -21731,6 +21731,100 @@ Generates the @code{cv.macsRN} machine instruction.
 Generates the @code{cv.machhsRN} machine instruction.
 @end deftypefn
 
+These built-in functions are available for the CORE-V ALU 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-miscellaneous-alu-builtins-xcvalu}
+
+@deftypefn {Built-in Function} {int} __builtin_riscv_cv_alu_slet (int32_t, int32_t)
+Generated assembler @code{cv.slet}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int} __builtin_riscv_cv_alu_sletu (uint32_t, uint32_t)
+Generated assembler @code{cv.sletu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_min (int32_t, int32_t)
+Generated assembler @code{cv.min}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_minu (uint32_t, uint32_t)
+Generated assembler @code{cv.minu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_max (int32_t, int32_t)
+Generated assembler @code{cv.max}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_tnt} __builtin_riscv_cv_alu_maxu (uint32_t, uint32_t)
+Generated assembler @code{cv.maxu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_exths (int16_t)
+Generated assembler @code{cv.exths}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_exthz (uint16_t)
+Generated assembler @code{cv.exthz}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_extbs (int8_t)
+Generated assembler @code{cv.extbs}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_extbz (uint8_t)
+Generated assembler @code{cv.extbz}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_clip (int32_t, uint32_t)
+Generated assembler @code{cv.clip} if the uint32_t operand is a constant and an exact power of 2.
+Generated assembler @code{cv.clipr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_clipu (uint32_t, uint32_t)
+Generated assembler @code{cv.clipu} if the uint32_t operand is a constant and an exact power of 2.
+Generated assembler @code{cv.clipur} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_addN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.addN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.addNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_adduN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.adduN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.adduNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_addRN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.addRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.addRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_adduRN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.adduRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.adduRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_subN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.subN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_subuN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.subuN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subuNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_subRN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.subRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_subuRN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.subuRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subuRNr} if  the it is a register.
+@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-alu-compile.c b/gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
new file mode 100644
index 00000000000..57289bb10eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
@@ -0,0 +1,252 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+#include <stdint.h>
+
+extern int d;
+extern int e;
+extern int f;
+
+void
+foo0(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, 0);
+  e = __builtin_riscv_cv_alu_addN (a, b, 7);
+  f = __builtin_riscv_cv_alu_addN (a, b, 31);
+}
+
+void
+foo1(int a, int b, int c)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, c);
+}
+
+void
+foo2(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_addRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_addRN (a, b, 31);
+}
+
+int
+foo3(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_addRN (a, b, c);
+}
+
+void
+foo4(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduN (a, b, 0);
+  e = __builtin_riscv_cv_alu_adduN (a, b, 7);
+  f = __builtin_riscv_cv_alu_adduN (a, b, 31);
+}
+
+int
+foo5(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_adduN (a, b, c);
+}
+
+void
+foo6(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_adduRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_adduRN (a, b, 31);
+}
+
+int
+foo7(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_adduRN (a, b, c);
+}
+
+int
+foo8(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clip (a, 15);
+}
+
+int
+foo9(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clip (a, 10);
+}
+
+int
+foo10(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clipu (a, 15);
+}
+
+int
+foo11(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clipu (a, 10);
+}
+
+int
+foo12(int a)
+{
+  return __builtin_riscv_cv_alu_extbs (a);
+}
+
+int
+foo13(int a)
+{
+  return __builtin_riscv_cv_alu_extbz (a);
+}
+
+int
+foo14(int b)
+{
+  return __builtin_riscv_cv_alu_exths (b);
+}
+
+int
+foo15(int a)
+{
+  return __builtin_riscv_cv_alu_exthz (a);
+}
+
+int
+foo16(int a, int b)
+{
+  return __builtin_riscv_cv_alu_max (a, b);
+}
+
+int
+foo17(int a, int b)
+{
+  return __builtin_riscv_cv_alu_maxu (a, b);
+}
+
+int
+foo18(int a, int b)
+{
+  return __builtin_riscv_cv_alu_min (a, b);
+}
+
+int
+foo19(int a, int b)
+{
+  return __builtin_riscv_cv_alu_minu (a, b);
+}
+
+int
+foo20(int a, int b)
+{
+  return __builtin_riscv_cv_alu_slet (a, b);
+}
+
+int
+foo21(unsigned int a, unsigned int b)
+{
+  return __builtin_riscv_cv_alu_sletu (a, b);
+}
+
+void
+foo22(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subN (a, b, 31);
+}
+
+int
+foo23(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subN (a, b, c);
+}
+
+void
+foo24(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subRN (a, b, 31);
+}
+
+int
+foo25(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subRN (a, b, c);
+}
+
+void
+foo26(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subuN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subuN (a, b, 31);
+}
+
+int
+foo27(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subuN (a, b, c);
+}
+
+void
+foo28(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subuRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subuRN (a, b, 31);
+}
+
+int
+foo29(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subuRN (a, b, c);
+}
+
+/* { dg-final { scan-assembler-times "cv\.addn\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 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\.addn\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\.addn\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\\.addnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addrn\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\.addrn\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\.addrn\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\\.addrnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addun\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 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\.addun\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\.addun\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\\.addunr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addurn\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\.addurn\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\.addurn\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\\.addurnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.clip\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),5" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.clipr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.clipu\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),5" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.clipur\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.extbs\t" 1 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\\.extbz\t" 1 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\\.exths\t" 1 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\\.exthz\t" 1 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\\.max\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.maxu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.min\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.minu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.sle\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.sleu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subn\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 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\.subn\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\.subn\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\\.subnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subrn\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\.subrn\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\.subrn\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\\.subrnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subun\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 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\.subun\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\.subun\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\\.subunr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.suburn\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\.suburn\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\.suburn\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\\.suburnr\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
new file mode 100644
index 00000000000..aa8610f4c2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
new file mode 100644
index 00000000000..12371b2c641
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
new file mode 100644
index 00000000000..3faad6c73c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
new file mode 100644
index 00000000000..39dc575b68e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
new file mode 100644
index 00000000000..a5ee231c74d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_clip (a, 4294967296); /* { dg-warning "overflow in conversion from \'long long int\' to \'int\' changes value from \'4294967296\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
new file mode 100644
index 00000000000..1ee11d2f600
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_clipu (a, 4294967296); /* { dg-warning "unsigned conversion from \'long long int\' to \'unsigned int\' changes value from \'4294967296\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
new file mode 100644
index 00000000000..91d6bd56672
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
new file mode 100644
index 00000000000..3c7e4ae63d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
new file mode 100644
index 00000000000..46218ea4451
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
new file mode 100644
index 00000000000..f20378dd839
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
new file mode 100644
index 00000000000..bbdb2d58c3f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i -mabi=ilp32" } */
+
+extern int d;
+
+int
+foo(int a, int b, int c)
+{
+    d += __builtin_riscv_cv_alu_slet (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_sletu (a, b);  /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_addN (a, b, 31);  /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_addRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_adduN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_adduRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_clip (a, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_clipu (a, 35); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_extbs (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_extbz (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_exths (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_exthz (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_min (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_minu (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_max (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_maxu (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subuN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subuRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+
+    return d;
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 45baf112983..f376fd1340c 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -12669,6 +12669,19 @@ proc check_effective_target_cv_mac { } {
     } "-march=rv32i_xcvmac" ]
 }
 
+# Return 1 if the CORE-V ALU extension is available.
+proc check_effective_target_cv_alu { } {
+    if { !([istarget riscv*-*-*]) } {
+         return 0
+     }
+    return [check_no_compiler_messages cv_alu object {
+        void foo (void)
+        {
+          asm ("cv.addn t0, t1, t2, 0");
+        }
+    } "-march=rv32i_xcvalu" ]
+}
+
 # Appends necessary Python flags to extra-tool-flags if Python.h is supported.
 # Otherwise, modifies dg-do-what.
 proc dg-require-python-h { args } {
-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions
  2023-09-27 12:26 ` [PATCH v2 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
  2023-09-27 12:26   ` [PATCH v2 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
  2023-09-27 12:26   ` [PATCH v2 2/2] RISC-V: Add support for XCValu " Mary Bennett
@ 2023-09-30 12:00   ` Mary Bennett
  2023-09-30 12:00     ` [PATCH v3 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
                       ` (3 more replies)
  2 siblings, 4 replies; 15+ messages in thread
From: Mary Bennett @ 2023-09-30 12:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: mary.bennett, rep.dot.nop

Thank you for reviewing this patch.

v1->v2:
  * Add XCValu RTL.
  * Change assembly mnemonics from mixed case to lower case.

v2->v3:
  * Change commit message from past tense to present.
  * Add documentation for new dg-effective-targets.

This patch series presents the comprehensive implementation of the MAC and ALU
extension for CORE-V.

Tested with riscv-gnu-toolchain on binutils, ld, gas and gcc testsuites to
ensure its correctness and compatibility with the existing codebase.
However, your input, reviews, and suggestions are invaluable in making this
extension even more robust.

The CORE-V builtins are described in the specification [1] and work can be
found in the OpenHW group's Github repository [2].

[1] github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md

[2] github.com/openhwgroup/corev-gcc

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>

  RISC-V: Add support for XCValu extension in CV32E40P
  RISC-V: Add support for XCVmac extension in CV32E40P

 gcc/common/config/riscv/riscv-common.cc       |   6 +
 gcc/config/riscv/constraints.md               |   7 +
 gcc/config/riscv/corev.def                    |  43 ++
 gcc/config/riscv/corev.md                     | 693 ++++++++++++++++++
 gcc/config/riscv/predicates.md                |   5 +
 gcc/config/riscv/riscv-builtins.cc            |  13 +
 gcc/config/riscv/riscv-ftypes.def             |  11 +
 gcc/config/riscv/riscv-opts.h                 |   7 +
 gcc/config/riscv/riscv.cc                     |   7 +
 gcc/config/riscv/riscv.md                     |   1 +
 gcc/config/riscv/riscv.opt                    |   3 +
 gcc/doc/extend.texi                           | 174 +++++
 gcc/doc/sourcebuild.texi                      |  12 +
 .../gcc.target/riscv/cv-alu-compile.c         | 252 +++++++
 .../riscv/cv-alu-fail-compile-addn.c          |  11 +
 .../riscv/cv-alu-fail-compile-addrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-addun.c         |  11 +
 .../riscv/cv-alu-fail-compile-addurn.c        |  11 +
 .../riscv/cv-alu-fail-compile-clip.c          |  11 +
 .../riscv/cv-alu-fail-compile-clipu.c         |  11 +
 .../riscv/cv-alu-fail-compile-subn.c          |  11 +
 .../riscv/cv-alu-fail-compile-subrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-subun.c         |  11 +
 .../riscv/cv-alu-fail-compile-suburn.c        |  11 +
 .../gcc.target/riscv/cv-alu-fail-compile.c    |  32 +
 .../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         |  26 +
 46 files changed, 2052 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-alu-compile.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
 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

-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 1/2] RISC-V: Add support for XCVmac extension in CV32E40P
  2023-09-30 12:00   ` [PATCH v3 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
@ 2023-09-30 12:00     ` Mary Bennett
  2023-09-30 12:00     ` [PATCH v3 2/2] RISC-V: Add support for XCValu " Mary Bennett
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 15+ messages in thread
From: Mary Bennett @ 2023-09-30 12:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: mary.bennett, rep.dot.nop

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: Add XCVmac.
	* config/riscv/riscv-ftypes.def: Add XCVmac builtins.
	* config/riscv/riscv-opts.h: Likewise.
	* config/riscv/riscv.md: Likewise.
	* config/riscv/riscv.opt: Likewise.
	* doc/extend.texi: Add XCVmac builtin documentation.
        * doc/sourcebuild.texi: Likewise.
	* config/riscv/corev.def: New file.
	* config/riscv/corev.md: New file.

gcc/testsuite/ChangeLog:

	* lib/target-supports.exp: Add 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/doc/sourcebuild.texi                      |   9 +
 .../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 +
 31 files changed, 1189 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

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..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-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 b4770f1a149..aede8541515 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -14938,6 +14938,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::
@@ -21680,6 +21681,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 f3043b2af1b..40b861555fd 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -12805,6 +12805,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 } {
-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 2/2] RISC-V: Add support for XCValu extension in CV32E40P
  2023-09-30 12:00   ` [PATCH v3 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
  2023-09-30 12:00     ` [PATCH v3 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
@ 2023-09-30 12:00     ` Mary Bennett
  2023-10-10 14:52     ` [PATCH v3 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Kito Cheng
  2023-10-11 12:06     ` [PATCH v4 " Mary Bennett
  3 siblings, 0 replies; 15+ messages in thread
From: Mary Bennett @ 2023-09-30 12:00 UTC (permalink / raw)
  To: gcc-patches; +Cc: mary.bennett, rep.dot.nop

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: Add the XCValu
	extension.
	* config/riscv/constraints.md: Add builtins for the XCValu
	extension.
	* config/riscv/predicates.md (immediate_register_operand):
	Likewise.
	* config/riscv/corev.def: Likewise.
	* config/riscv/corev.md: Likewise.
	* config/riscv/riscv-builtins.cc (AVAIL): Likewise.
	  (RISCV_ATYPE_UHI): Likewise.
	* config/riscv/riscv-ftypes.def: Likewise.
	* config/riscv/riscv-opts.h: Likewise.
	* config/riscv/riscv.opt: Likewise.
	* config/riscv/riscv.cc (riscv_print_operand): Likewise.
	* doc/extend.texi: Add XCValu documentation.
        * doc/sourcebuild.texi: Likewise.

gcc/testsuite/ChangeLog:

	* lib/target-supports.exp: Add proc for the XCValu extension.
	* gcc.target/riscv/cv-alu-compile.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addrn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addun.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addurn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-clip.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-clipu.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subrn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subun.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-suburn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile.c: New test.
---
 gcc/common/config/riscv/riscv-common.cc       |   2 +
 gcc/config/riscv/constraints.md               |   7 +
 gcc/config/riscv/corev.def                    |  24 ++
 gcc/config/riscv/corev.md                     | 303 ++++++++++++++++++
 gcc/config/riscv/predicates.md                |   5 +
 gcc/config/riscv/riscv-builtins.cc            |   3 +
 gcc/config/riscv/riscv-ftypes.def             |   6 +
 gcc/config/riscv/riscv-opts.h                 |   2 +
 gcc/config/riscv/riscv.cc                     |   7 +
 gcc/doc/extend.texi                           |  94 ++++++
 gcc/doc/sourcebuild.texi                      |   3 +
 .../gcc.target/riscv/cv-alu-compile.c         | 252 +++++++++++++++
 .../riscv/cv-alu-fail-compile-addn.c          |  11 +
 .../riscv/cv-alu-fail-compile-addrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-addun.c         |  11 +
 .../riscv/cv-alu-fail-compile-addurn.c        |  11 +
 .../riscv/cv-alu-fail-compile-clip.c          |  11 +
 .../riscv/cv-alu-fail-compile-clipu.c         |  11 +
 .../riscv/cv-alu-fail-compile-subn.c          |  11 +
 .../riscv/cv-alu-fail-compile-subrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-subun.c         |  11 +
 .../riscv/cv-alu-fail-compile-suburn.c        |  11 +
 .../gcc.target/riscv/cv-alu-fail-compile.c    |  32 ++
 gcc/testsuite/lib/target-supports.exp         |  13 +
 24 files changed, 863 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c

diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 53e21fa4bce..e7c1a99fbd2 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -311,6 +311,7 @@ static const struct riscv_ext_version riscv_ext_version_table[] =
   {"svpbmt",  ISA_SPEC_CLASS_NONE, 1, 0},
 
   {"xcvmac", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xcvalu", ISA_SPEC_CLASS_NONE, 1, 0},
 
   {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1483,6 +1484,7 @@ 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},
+  {"xcvalu",        &gcc_options::x_riscv_xcv_flags, MASK_XCVALU},
 
   {"xtheadba",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBA},
   {"xtheadbb",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBB},
diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index 964fdd450c9..07ee14dd689 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -151,6 +151,13 @@
 (define_register_constraint "zmvr" "(TARGET_ZFA || TARGET_XTHEADFMV) ? GR_REGS : NO_REGS"
   "An integer register for  ZFA or XTheadFmv.")
 
+;; CORE-V Constraints
+(define_constraint "CVP2"
+  "Checking for CORE-V ALU clip if ival plus 1 is a power of 2"
+  (and (match_code "const_int")
+       (and (match_test "IN_RANGE (ival, 0, 1073741823)")
+            (match_test "exact_log2 (ival + 1) != -1"))))
+
 ;; Vector constraints.
 
 (define_register_constraint "vr" "TARGET_VECTOR ? V_REGS : NO_REGS"
diff --git a/gcc/config/riscv/corev.def b/gcc/config/riscv/corev.def
index a4e94680d8e..17580df3c41 100644
--- a/gcc/config/riscv/corev.def
+++ b/gcc/config/riscv/corev.def
@@ -17,3 +17,27 @@ RISCV_BUILTIN (cv_mac_macuRN,    "cv_mac_macuRN",     RISCV_BUILTIN_DIRECT, RISC
 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),
+
+// XCVALU
+RISCV_BUILTIN (cv_alu_slet,     "cv_alu_slet",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_sletu,    "cv_alu_sletu", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_USI_USI,   cvalu),
+RISCV_BUILTIN (cv_alu_min,      "cv_alu_min",   RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_minu,     "cv_alu_minu",  RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+RISCV_BUILTIN (cv_alu_max,      "cv_alu_max",   RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_maxu,     "cv_alu_maxu",  RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+
+RISCV_BUILTIN (cv_alu_exths,    "cv_alu_exths", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_HI,        cvalu),
+RISCV_BUILTIN (cv_alu_exthz,    "cv_alu_exthz", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_UHI,      cvalu),
+RISCV_BUILTIN (cv_alu_extbs,    "cv_alu_extbs", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_QI,        cvalu),
+RISCV_BUILTIN (cv_alu_extbz,    "cv_alu_extbz", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_UQI,      cvalu),
+
+RISCV_BUILTIN (cv_alu_clip,     "cv_alu_clip",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_clipu,    "cv_alu_clipu", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+RISCV_BUILTIN (cv_alu_addN,     "cv_alu_addN",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_adduN,    "cv_alu_adduN", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_addRN,    "cv_alu_addRN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_adduRN,   "cv_alu_adduRN",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_subN,     "cv_alu_subN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_subuN,    "cv_alu_subuN", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_subRN,    "cv_alu_subRN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_subuRN,   "cv_alu_subuRN",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
diff --git a/gcc/config/riscv/corev.md b/gcc/config/riscv/corev.md
index 65ce09ea6eb..1350bd4b81e 100644
--- a/gcc/config/riscv/corev.md
+++ b/gcc/config/riscv/corev.md
@@ -17,6 +17,15 @@
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.
 
+(define_c_enum "unspec" [
+
+  ;;CORE-V ALU
+  UNSPEC_CV_ALU_CLIP
+  UNSPEC_CV_ALU_CLIPR
+  UNSPEC_CV_ALU_CLIPU
+  UNSPEC_CV_ALU_CLIPUR
+])
+
 ;; XCVMAC extension.
 
 (define_insn "riscv_cv_mac_mac"
@@ -388,3 +397,297 @@
   "cv.machhsrn\t%0,%1,%2,%4"
   [(set_attr "type" "arith")
   (set_attr "mode" "SI")])
+
+;; XCVALU builtins
+
+(define_insn "riscv_cv_alu_slet"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (le:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.sle\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_sletu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (leu:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.sleu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_min"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (smin:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.min\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_minu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (umin:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.minu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_max"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (smax:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.max\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_maxu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (umax:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.maxu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_exths"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (sign_extend:SI
+     (truncate:HI
+       (match_operand:HI 1 "register_operand" "r"))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.exths\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_exthz"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (zero_extend:SI
+     (truncate:HI
+       (match_operand:HI 1 "register_operand" "r"))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.exthz\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_extbs"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (sign_extend:SI
+     (truncate:QI
+       (match_operand:QI 1 "register_operand" "r"))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.extbs\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_extbz"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (zero_extend:SI
+     (truncate:QI
+   (match_operand:QI 1 "register_operand" "r"))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.extbz\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_clip"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
+    UNSPEC_CV_ALU_CLIP))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.clip\t%0,%1,%X2
+  cv.clipr\t%0,%1,%2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_clipu"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
+    UNSPEC_CV_ALU_CLIPU))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.clipu\t%0,%1,%X2
+  cv.clipur\t%0,%1,%2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_addN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (ashiftrt:SI
+      (plus:SI
+        (match_operand:SI 1 "register_operand" "r,0")
+        (match_operand:SI 2 "register_operand" "r,r"))
+      (and:SI (match_operand:QI 3 "csr_operand" "K,r")
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addn\t%0,%1,%2,%3
+  cv.addnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_adduN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (lshiftrt:SI
+      (plus:SI
+        (match_operand:SI 1 "register_operand" "r,0")
+        (match_operand:SI 2 "register_operand" "r,r"))
+      (and:SI (match_operand:QI 3 "csr_operand" "K,r")
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addun\t%0,%1,%2,%3
+  cv.addunr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_addRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (ashiftrt:SI
+      (plus:SI
+        (plus:SI
+          (match_operand:SI 1 "register_operand" "r,0")
+          (match_operand:SI 2 "register_operand" "r,r"))
+        (if_then_else (eq (match_operand:QI 3 "csr_operand" "K,r")
+                          (const_int 0))
+          (const_int 1)
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))))
+      (and:SI (match_dup 3)
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addrn\t%0,%1,%2,%3
+  cv.addrnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_adduRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (lshiftrt:SI
+      (plus:SI
+        (plus:SI
+          (match_operand:SI 1 "register_operand" "r,0")
+          (match_operand:SI 2 "register_operand" "r,r"))
+        (if_then_else (eq (match_operand:QI 3 "csr_operand" "K,r")
+                          (const_int 0))
+          (const_int 1)
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))))
+      (and:SI (match_dup 3)
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addurn\t%0,%1,%2,%3
+  cv.addurnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (ashiftrt:SI
+      (minus:SI
+        (match_operand:SI 1 "register_operand" "r,0")
+        (match_operand:SI 2 "register_operand" "r,r"))
+      (and:SI (match_operand:QI 3 "csr_operand" "K,r")
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subn\t%0,%1,%2,%3
+  cv.subnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subuN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (lshiftrt:SI
+      (minus:SI
+        (match_operand:SI 1 "register_operand" "r,0")
+        (match_operand:SI 2 "register_operand" "r,r"))
+      (and:SI (match_operand:QI 3 "csr_operand" "K,r")
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subun\t%0,%1,%2,%3
+  cv.subunr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (ashiftrt:SI
+      (plus:SI
+        (minus:SI
+          (match_operand:SI 1 "register_operand" "r,0")
+          (match_operand:SI 2 "register_operand" "r,r"))
+        (if_then_else (eq (match_operand:QI 3 "csr_operand" "K,r")
+                          (const_int 0))
+          (const_int 1)
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))))
+      (and:SI (match_dup 3)
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subrn\t%0,%1,%2,%3
+  cv.subrnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subuRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (lshiftrt:SI
+      (plus:SI
+        (minus:SI
+          (match_operand:SI 1 "register_operand" "r,0")
+          (match_operand:SI 2 "register_operand" "r,r"))
+        (if_then_else (eq (match_operand:QI 3 "csr_operand" "K,r")
+                          (const_int 0))
+          (const_int 1)
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))))
+      (and:SI (match_dup 3)
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.suburn\t%0,%1,%2,%3
+  cv.suburnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 6b72a5f4e07..a37d035fa61 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -395,6 +395,11 @@
 	return true;
 })
 
+;; CORE-V Predicates:
+(define_predicate "immediate_register_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_code "const_int")))
+
 ;; Predicates for the V extension.
 (define_special_predicate "vector_length_operand"
   (ior (match_operand 0 "pmode_register_operand")
diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc
index 1f733337b82..fc3976f3ba1 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -127,6 +127,7 @@ AVAIL (hint_pause, (!0))
 
 // CORE-V AVAIL
 AVAIL (cvmac, TARGET_XCVMAC && !TARGET_64BIT)
+AVAIL (cvalu, TARGET_XCVALU && !TARGET_64BIT)
 
 /* Construct a riscv_builtin_description from the given arguments.
 
@@ -163,6 +164,8 @@ AVAIL (cvmac, TARGET_XCVMAC && !TARGET_64BIT)
 #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_QI intQI_type_node
+#define RISCV_ATYPE_HI intHI_type_node
 #define RISCV_ATYPE_SI intSI_type_node
 #define RISCV_ATYPE_VOID_PTR ptr_type_node
 
diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def
index 430a4c2d673..0d1e4dd061e 100644
--- a/gcc/config/riscv/riscv-ftypes.def
+++ b/gcc/config/riscv/riscv-ftypes.def
@@ -32,6 +32,10 @@ DEF_RISCV_FTYPE (1, (VOID, USI))
 DEF_RISCV_FTYPE (1, (VOID, VOID_PTR))
 DEF_RISCV_FTYPE (1, (USI, USI))
 DEF_RISCV_FTYPE (1, (UDI, UDI))
+DEF_RISCV_FTYPE (1, (USI, UQI))
+DEF_RISCV_FTYPE (1, (USI, UHI))
+DEF_RISCV_FTYPE (1, (SI, QI))
+DEF_RISCV_FTYPE (1, (SI, HI))
 DEF_RISCV_FTYPE (2, (USI, UQI, UQI))
 DEF_RISCV_FTYPE (2, (USI, UHI, UHI))
 DEF_RISCV_FTYPE (2, (USI, USI, USI))
@@ -40,6 +44,8 @@ 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 (2, (SI, USI, USI))
+DEF_RISCV_FTYPE (2, (SI, SI, SI))
 DEF_RISCV_FTYPE (3, (USI, USI, USI, UQI))
 DEF_RISCV_FTYPE (3, (USI, USI, USI, USI))
 DEF_RISCV_FTYPE (3, (SI, SI, SI, UQI))
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 8b0aa1d1b41..ec929bc5fe9 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -296,6 +296,7 @@ enum riscv_entity
    : 32 << (__builtin_popcount (riscv_zvl_flags) - 1))
 
 #define MASK_XCVMAC    (1 <<  0)
+#define MASK_XCVALU    (1 <<  1)
 
 #define MASK_XTHEADBA      (1 << 0)
 #define MASK_XTHEADBB      (1 << 1)
@@ -312,6 +313,7 @@ enum riscv_entity
 
 
 #define TARGET_XCVMAC    ((riscv_xcv_flags & MASK_XCVMAC) != 0)
+#define TARGET_XCVALU    ((riscv_xcv_flags & MASK_XCVALU) != 0)
 
 #define TARGET_XTHEADBA      ((riscv_xthead_subext & MASK_XTHEADBA) != 0)
 #define TARGET_XTHEADBB      ((riscv_xthead_subext & MASK_XTHEADBB) != 0)
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 6e7a719e7a0..03bf8b52148 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -5633,6 +5633,13 @@ riscv_print_operand (FILE *file, rtx op, int letter)
 	output_addr_const (file, newop);
 	break;
       }
+    case 'X':
+      {
+	int ival = INTVAL (op) + 1;
+	rtx newop = GEN_INT (ctz_hwi (ival) + 1);
+	output_addr_const (file, newop);
+	break;
+      }
     default:
       switch (code)
 	{
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index aede8541515..5036bd546e6 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -21760,6 +21760,100 @@ Generates the @code{cv.macsRN} machine instruction.
 Generates the @code{cv.machhsRN} machine instruction.
 @end deftypefn
 
+These built-in functions are available for the CORE-V ALU 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-miscellaneous-alu-builtins-xcvalu}
+
+@deftypefn {Built-in Function} {int} __builtin_riscv_cv_alu_slet (int32_t, int32_t)
+Generated assembler @code{cv.slet}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int} __builtin_riscv_cv_alu_sletu (uint32_t, uint32_t)
+Generated assembler @code{cv.sletu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_min (int32_t, int32_t)
+Generated assembler @code{cv.min}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_minu (uint32_t, uint32_t)
+Generated assembler @code{cv.minu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_max (int32_t, int32_t)
+Generated assembler @code{cv.max}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_tnt} __builtin_riscv_cv_alu_maxu (uint32_t, uint32_t)
+Generated assembler @code{cv.maxu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_exths (int16_t)
+Generated assembler @code{cv.exths}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_exthz (uint16_t)
+Generated assembler @code{cv.exthz}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_extbs (int8_t)
+Generated assembler @code{cv.extbs}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_extbz (uint8_t)
+Generated assembler @code{cv.extbz}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_clip (int32_t, uint32_t)
+Generated assembler @code{cv.clip} if the uint32_t operand is a constant and an exact power of 2.
+Generated assembler @code{cv.clipr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_clipu (uint32_t, uint32_t)
+Generated assembler @code{cv.clipu} if the uint32_t operand is a constant and an exact power of 2.
+Generated assembler @code{cv.clipur} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_addN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.addN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.addNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_adduN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.adduN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.adduNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_addRN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.addRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.addRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_adduRN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.adduRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.adduRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_subN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.subN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_subuN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.subuN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subuNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_subRN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.subRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_subuRN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.subuRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subuRNr} if  the it is a register.
+@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 1e1e61a5d67..0cff2e8953a 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -2478,6 +2478,9 @@ Test system has an integer register width of 64 bits.
 @item cv_mac
 Test system has support for the CORE-V MAC extension.
 
+@item cv_alu
+Test system has support for the CORE-V ALU extension.
+
 @end table
 
 @subsubsection Other hardware attributes
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-compile.c b/gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
new file mode 100644
index 00000000000..57289bb10eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
@@ -0,0 +1,252 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+#include <stdint.h>
+
+extern int d;
+extern int e;
+extern int f;
+
+void
+foo0(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, 0);
+  e = __builtin_riscv_cv_alu_addN (a, b, 7);
+  f = __builtin_riscv_cv_alu_addN (a, b, 31);
+}
+
+void
+foo1(int a, int b, int c)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, c);
+}
+
+void
+foo2(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_addRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_addRN (a, b, 31);
+}
+
+int
+foo3(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_addRN (a, b, c);
+}
+
+void
+foo4(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduN (a, b, 0);
+  e = __builtin_riscv_cv_alu_adduN (a, b, 7);
+  f = __builtin_riscv_cv_alu_adduN (a, b, 31);
+}
+
+int
+foo5(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_adduN (a, b, c);
+}
+
+void
+foo6(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_adduRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_adduRN (a, b, 31);
+}
+
+int
+foo7(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_adduRN (a, b, c);
+}
+
+int
+foo8(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clip (a, 15);
+}
+
+int
+foo9(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clip (a, 10);
+}
+
+int
+foo10(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clipu (a, 15);
+}
+
+int
+foo11(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clipu (a, 10);
+}
+
+int
+foo12(int a)
+{
+  return __builtin_riscv_cv_alu_extbs (a);
+}
+
+int
+foo13(int a)
+{
+  return __builtin_riscv_cv_alu_extbz (a);
+}
+
+int
+foo14(int b)
+{
+  return __builtin_riscv_cv_alu_exths (b);
+}
+
+int
+foo15(int a)
+{
+  return __builtin_riscv_cv_alu_exthz (a);
+}
+
+int
+foo16(int a, int b)
+{
+  return __builtin_riscv_cv_alu_max (a, b);
+}
+
+int
+foo17(int a, int b)
+{
+  return __builtin_riscv_cv_alu_maxu (a, b);
+}
+
+int
+foo18(int a, int b)
+{
+  return __builtin_riscv_cv_alu_min (a, b);
+}
+
+int
+foo19(int a, int b)
+{
+  return __builtin_riscv_cv_alu_minu (a, b);
+}
+
+int
+foo20(int a, int b)
+{
+  return __builtin_riscv_cv_alu_slet (a, b);
+}
+
+int
+foo21(unsigned int a, unsigned int b)
+{
+  return __builtin_riscv_cv_alu_sletu (a, b);
+}
+
+void
+foo22(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subN (a, b, 31);
+}
+
+int
+foo23(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subN (a, b, c);
+}
+
+void
+foo24(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subRN (a, b, 31);
+}
+
+int
+foo25(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subRN (a, b, c);
+}
+
+void
+foo26(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subuN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subuN (a, b, 31);
+}
+
+int
+foo27(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subuN (a, b, c);
+}
+
+void
+foo28(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subuRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subuRN (a, b, 31);
+}
+
+int
+foo29(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subuRN (a, b, c);
+}
+
+/* { dg-final { scan-assembler-times "cv\.addn\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 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\.addn\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\.addn\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\\.addnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addrn\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\.addrn\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\.addrn\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\\.addrnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addun\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 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\.addun\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\.addun\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\\.addunr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addurn\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\.addurn\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\.addurn\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\\.addurnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.clip\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),5" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.clipr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.clipu\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),5" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.clipur\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.extbs\t" 1 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\\.extbz\t" 1 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\\.exths\t" 1 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\\.exthz\t" 1 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\\.max\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.maxu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.min\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.minu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.sle\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.sleu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subn\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 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\.subn\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\.subn\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\\.subnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subrn\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\.subrn\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\.subrn\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\\.subrnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subun\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 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\.subun\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\.subun\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\\.subunr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.suburn\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\.suburn\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\.suburn\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\\.suburnr\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
new file mode 100644
index 00000000000..aa8610f4c2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
new file mode 100644
index 00000000000..12371b2c641
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
new file mode 100644
index 00000000000..3faad6c73c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
new file mode 100644
index 00000000000..39dc575b68e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
new file mode 100644
index 00000000000..a5ee231c74d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_clip (a, 4294967296); /* { dg-warning "overflow in conversion from \'long long int\' to \'int\' changes value from \'4294967296\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
new file mode 100644
index 00000000000..1ee11d2f600
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_clipu (a, 4294967296); /* { dg-warning "unsigned conversion from \'long long int\' to \'unsigned int\' changes value from \'4294967296\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
new file mode 100644
index 00000000000..91d6bd56672
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
new file mode 100644
index 00000000000..3c7e4ae63d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
new file mode 100644
index 00000000000..46218ea4451
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
new file mode 100644
index 00000000000..f20378dd839
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
new file mode 100644
index 00000000000..bbdb2d58c3f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i -mabi=ilp32" } */
+
+extern int d;
+
+int
+foo(int a, int b, int c)
+{
+    d += __builtin_riscv_cv_alu_slet (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_sletu (a, b);  /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_addN (a, b, 31);  /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_addRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_adduN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_adduRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_clip (a, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_clipu (a, 35); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_extbs (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_extbz (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_exths (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_exthz (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_min (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_minu (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_max (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_maxu (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subuN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subuRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+
+    return d;
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 40b861555fd..e9e304c5029 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -12818,6 +12818,19 @@ proc check_effective_target_cv_mac { } {
     } "-march=rv32i_xcvmac" ]
 }
 
+# Return 1 if the CORE-V ALU extension is available.
+proc check_effective_target_cv_alu { } {
+    if { !([istarget riscv*-*-*]) } {
+         return 0
+     }
+    return [check_no_compiler_messages cv_alu object {
+        void foo (void)
+        {
+          asm ("cv.addn t0, t1, t2, 0");
+        }
+    } "-march=rv32i_xcvalu" ]
+}
+
 # Appends necessary Python flags to extra-tool-flags if Python.h is supported.
 # Otherwise, modifies dg-do-what.
 proc dg-require-python-h { args } {
-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions
  2023-09-30 12:00   ` [PATCH v3 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
  2023-09-30 12:00     ` [PATCH v3 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
  2023-09-30 12:00     ` [PATCH v3 2/2] RISC-V: Add support for XCValu " Mary Bennett
@ 2023-10-10 14:52     ` Kito Cheng
  2023-10-11 12:06     ` [PATCH v4 " Mary Bennett
  3 siblings, 0 replies; 15+ messages in thread
From: Kito Cheng @ 2023-10-10 14:52 UTC (permalink / raw)
  To: Mary Bennett; +Cc: gcc-patches, rep.dot.nop

Just repeat what I said on the mailing list again :P it's LGTM, just
need to rebase to deal with riscv.opt related changes :)


On Sat, Sep 30, 2023 at 8:02 PM Mary Bennett <mary.bennett@embecosm.com> wrote:
>
> Thank you for reviewing this patch.
>
> v1->v2:
>   * Add XCValu RTL.
>   * Change assembly mnemonics from mixed case to lower case.
>
> v2->v3:
>   * Change commit message from past tense to present.
>   * Add documentation for new dg-effective-targets.
>
> This patch series presents the comprehensive implementation of the MAC and ALU
> extension for CORE-V.
>
> Tested with riscv-gnu-toolchain on binutils, ld, gas and gcc testsuites to
> ensure its correctness and compatibility with the existing codebase.
> However, your input, reviews, and suggestions are invaluable in making this
> extension even more robust.
>
> The CORE-V builtins are described in the specification [1] and work can be
> found in the OpenHW group's Github repository [2].
>
> [1] github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md
>
> [2] github.com/openhwgroup/corev-gcc
>
> 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>
>
>   RISC-V: Add support for XCValu extension in CV32E40P
>   RISC-V: Add support for XCVmac extension in CV32E40P
>
>  gcc/common/config/riscv/riscv-common.cc       |   6 +
>  gcc/config/riscv/constraints.md               |   7 +
>  gcc/config/riscv/corev.def                    |  43 ++
>  gcc/config/riscv/corev.md                     | 693 ++++++++++++++++++
>  gcc/config/riscv/predicates.md                |   5 +
>  gcc/config/riscv/riscv-builtins.cc            |  13 +
>  gcc/config/riscv/riscv-ftypes.def             |  11 +
>  gcc/config/riscv/riscv-opts.h                 |   7 +
>  gcc/config/riscv/riscv.cc                     |   7 +
>  gcc/config/riscv/riscv.md                     |   1 +
>  gcc/config/riscv/riscv.opt                    |   3 +
>  gcc/doc/extend.texi                           | 174 +++++
>  gcc/doc/sourcebuild.texi                      |  12 +
>  .../gcc.target/riscv/cv-alu-compile.c         | 252 +++++++
>  .../riscv/cv-alu-fail-compile-addn.c          |  11 +
>  .../riscv/cv-alu-fail-compile-addrn.c         |  11 +
>  .../riscv/cv-alu-fail-compile-addun.c         |  11 +
>  .../riscv/cv-alu-fail-compile-addurn.c        |  11 +
>  .../riscv/cv-alu-fail-compile-clip.c          |  11 +
>  .../riscv/cv-alu-fail-compile-clipu.c         |  11 +
>  .../riscv/cv-alu-fail-compile-subn.c          |  11 +
>  .../riscv/cv-alu-fail-compile-subrn.c         |  11 +
>  .../riscv/cv-alu-fail-compile-subun.c         |  11 +
>  .../riscv/cv-alu-fail-compile-suburn.c        |  11 +
>  .../gcc.target/riscv/cv-alu-fail-compile.c    |  32 +
>  .../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         |  26 +
>  46 files changed, 2052 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-alu-compile.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
>  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
>
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v4 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions
  2023-09-30 12:00   ` [PATCH v3 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
                       ` (2 preceding siblings ...)
  2023-10-10 14:52     ` [PATCH v3 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Kito Cheng
@ 2023-10-11 12:06     ` Mary Bennett
  2023-10-11 12:06       ` [PATCH v4 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
                         ` (2 more replies)
  3 siblings, 3 replies; 15+ messages in thread
From: Mary Bennett @ 2023-10-11 12:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: mary.bennett

This patch series presents the comprehensive implementation of the MAC and ALU
extension for CORE-V.

Tested with riscv-gnu-toolchain on binutils, ld, gas and gcc testsuites to
ensure its correctness and compatibility with the existing codebase.
However, your input, reviews, and suggestions are invaluable in making this
extension even more robust.

The CORE-V builtins are described in the specification [1] and work can be
found in the OpenHW group's Github repository [2].

[1] github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md

[2] github.com/openhwgroup/corev-gcc

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>

  RISC-V: Add support for XCValu extension in CV32E40P
  RISC-V: Add support for XCVmac extension in CV32E40P

 gcc/common/config/riscv/riscv-common.cc       |   6 +
 gcc/config/riscv/constraints.md               |   7 +
 gcc/config/riscv/corev.def                    |  43 ++
 gcc/config/riscv/corev.md                     | 693 ++++++++++++++++++
 gcc/config/riscv/predicates.md                |   5 +
 gcc/config/riscv/riscv-builtins.cc            |  13 +
 gcc/config/riscv/riscv-ftypes.def             |  11 +
 gcc/config/riscv/riscv.cc                     |   7 +
 gcc/config/riscv/riscv.md                     |   1 +
 gcc/config/riscv/riscv.opt                    |   7 +
 gcc/doc/extend.texi                           | 174 +++++
 gcc/doc/sourcebuild.texi                      |  12 +
 .../gcc.target/riscv/cv-alu-compile.c         | 252 +++++++
 .../riscv/cv-alu-fail-compile-addn.c          |  11 +
 .../riscv/cv-alu-fail-compile-addrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-addun.c         |  11 +
 .../riscv/cv-alu-fail-compile-addurn.c        |  11 +
 .../riscv/cv-alu-fail-compile-clip.c          |  11 +
 .../riscv/cv-alu-fail-compile-clipu.c         |  11 +
 .../riscv/cv-alu-fail-compile-subn.c          |  11 +
 .../riscv/cv-alu-fail-compile-subrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-subun.c         |  11 +
 .../riscv/cv-alu-fail-compile-suburn.c        |  11 +
 .../gcc.target/riscv/cv-alu-fail-compile.c    |  32 +
 .../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         |  26 +
 45 files changed, 2049 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-alu-compile.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
 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

-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v4 1/2] RISC-V: Add support for XCVmac extension in CV32E40P
  2023-10-11 12:06     ` [PATCH v4 " Mary Bennett
@ 2023-10-11 12:06       ` Mary Bennett
  2023-10-11 12:06       ` [PATCH v4 2/2] RISC-V: Add support for XCValu " Mary Bennett
  2023-10-11 13:49       ` [PATCH v4 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Jeff Law
  2 siblings, 0 replies; 15+ messages in thread
From: Mary Bennett @ 2023-10-11 12:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: mary.bennett

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: Add XCVmac.
	* config/riscv/riscv-ftypes.def: Add XCVmac builtins.
	* config/riscv/riscv-opts.h: Likewise.
	* config/riscv/riscv.md: Likewise.
	* config/riscv/riscv.opt: Likewise.
	* doc/extend.texi: Add XCVmac builtin documentation.
        * doc/sourcebuild.texi: Likewise.
	* config/riscv/corev.def: New file.
	* config/riscv/corev.md: New file.

gcc/testsuite/ChangeLog:

	* lib/target-supports.exp: Add 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.md                     |   1 +
 gcc/config/riscv/riscv.opt                    |   5 +
 gcc/doc/extend.texi                           |  80 ++++
 gcc/doc/sourcebuild.texi                      |   9 +
 .../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, 1186 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

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 } {
-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v4 2/2] RISC-V: Add support for XCValu extension in CV32E40P
  2023-10-11 12:06     ` [PATCH v4 " Mary Bennett
  2023-10-11 12:06       ` [PATCH v4 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
@ 2023-10-11 12:06       ` Mary Bennett
  2023-10-11 13:49       ` [PATCH v4 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Jeff Law
  2 siblings, 0 replies; 15+ messages in thread
From: Mary Bennett @ 2023-10-11 12:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: mary.bennett

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: Add the XCValu
	extension.
	* config/riscv/constraints.md: Add builtins for the XCValu
	extension.
	* config/riscv/predicates.md (immediate_register_operand):
	Likewise.
	* config/riscv/corev.def: Likewise.
	* config/riscv/corev.md: Likewise.
	* config/riscv/riscv-builtins.cc (AVAIL): Likewise.
	  (RISCV_ATYPE_UHI): Likewise.
	* config/riscv/riscv-ftypes.def: Likewise.
	* config/riscv/riscv-opts.h: Likewise.
	* config/riscv/riscv.opt: Likewise.
	* config/riscv/riscv.cc (riscv_print_operand): Likewise.
	* doc/extend.texi: Add XCValu documentation.
        * doc/sourcebuild.texi: Likewise.

gcc/testsuite/ChangeLog:

	* lib/target-supports.exp: Add proc for the XCValu extension.
	* gcc.target/riscv/cv-alu-compile.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addrn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addun.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-addurn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-clip.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-clipu.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subrn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-subun.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile-suburn.c: New test.
	* gcc.target/riscv/cv-alu-fail-compile.c: New test.
---
 gcc/common/config/riscv/riscv-common.cc       |   2 +
 gcc/config/riscv/constraints.md               |   7 +
 gcc/config/riscv/corev.def                    |  24 ++
 gcc/config/riscv/corev.md                     | 303 ++++++++++++++++++
 gcc/config/riscv/predicates.md                |   5 +
 gcc/config/riscv/riscv-builtins.cc            |   3 +
 gcc/config/riscv/riscv-ftypes.def             |   6 +
 gcc/config/riscv/riscv.cc                     |   7 +
 gcc/config/riscv/riscv.opt                    |   2 +
 gcc/doc/extend.texi                           |  94 ++++++
 gcc/doc/sourcebuild.texi                      |   3 +
 .../gcc.target/riscv/cv-alu-compile.c         | 252 +++++++++++++++
 .../riscv/cv-alu-fail-compile-addn.c          |  11 +
 .../riscv/cv-alu-fail-compile-addrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-addun.c         |  11 +
 .../riscv/cv-alu-fail-compile-addurn.c        |  11 +
 .../riscv/cv-alu-fail-compile-clip.c          |  11 +
 .../riscv/cv-alu-fail-compile-clipu.c         |  11 +
 .../riscv/cv-alu-fail-compile-subn.c          |  11 +
 .../riscv/cv-alu-fail-compile-subrn.c         |  11 +
 .../riscv/cv-alu-fail-compile-subun.c         |  11 +
 .../riscv/cv-alu-fail-compile-suburn.c        |  11 +
 .../gcc.target/riscv/cv-alu-fail-compile.c    |  32 ++
 gcc/testsuite/lib/target-supports.exp         |  13 +
 24 files changed, 863 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c

diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 62de116803e..908e8e0c8bd 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -311,6 +311,7 @@ static const struct riscv_ext_version riscv_ext_version_table[] =
   {"svpbmt",  ISA_SPEC_CLASS_NONE, 1, 0},
 
   {"xcvmac", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xcvalu", ISA_SPEC_CLASS_NONE, 1, 0},
 
   {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1483,6 +1484,7 @@ 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},
+  {"xcvalu",        &gcc_options::x_riscv_xcv_subext, MASK_XCVALU},
 
   {"xtheadba",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBA},
   {"xtheadbb",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBB},
diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index 964fdd450c9..07ee14dd689 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -151,6 +151,13 @@
 (define_register_constraint "zmvr" "(TARGET_ZFA || TARGET_XTHEADFMV) ? GR_REGS : NO_REGS"
   "An integer register for  ZFA or XTheadFmv.")
 
+;; CORE-V Constraints
+(define_constraint "CVP2"
+  "Checking for CORE-V ALU clip if ival plus 1 is a power of 2"
+  (and (match_code "const_int")
+       (and (match_test "IN_RANGE (ival, 0, 1073741823)")
+            (match_test "exact_log2 (ival + 1) != -1"))))
+
 ;; Vector constraints.
 
 (define_register_constraint "vr" "TARGET_VECTOR ? V_REGS : NO_REGS"
diff --git a/gcc/config/riscv/corev.def b/gcc/config/riscv/corev.def
index a4e94680d8e..17580df3c41 100644
--- a/gcc/config/riscv/corev.def
+++ b/gcc/config/riscv/corev.def
@@ -17,3 +17,27 @@ RISCV_BUILTIN (cv_mac_macuRN,    "cv_mac_macuRN",     RISCV_BUILTIN_DIRECT, RISC
 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),
+
+// XCVALU
+RISCV_BUILTIN (cv_alu_slet,     "cv_alu_slet",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_sletu,    "cv_alu_sletu", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_USI_USI,   cvalu),
+RISCV_BUILTIN (cv_alu_min,      "cv_alu_min",   RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_minu,     "cv_alu_minu",  RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+RISCV_BUILTIN (cv_alu_max,      "cv_alu_max",   RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_maxu,     "cv_alu_maxu",  RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+
+RISCV_BUILTIN (cv_alu_exths,    "cv_alu_exths", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_HI,        cvalu),
+RISCV_BUILTIN (cv_alu_exthz,    "cv_alu_exthz", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_UHI,      cvalu),
+RISCV_BUILTIN (cv_alu_extbs,    "cv_alu_extbs", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_QI,        cvalu),
+RISCV_BUILTIN (cv_alu_extbz,    "cv_alu_extbz", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_UQI,      cvalu),
+
+RISCV_BUILTIN (cv_alu_clip,     "cv_alu_clip",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI,     cvalu),
+RISCV_BUILTIN (cv_alu_clipu,    "cv_alu_clipu", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,  cvalu),
+RISCV_BUILTIN (cv_alu_addN,     "cv_alu_addN",  RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_adduN,    "cv_alu_adduN", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_addRN,    "cv_alu_addRN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_adduRN,   "cv_alu_adduRN",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_subN,     "cv_alu_subN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_subuN,    "cv_alu_subuN", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
+RISCV_BUILTIN (cv_alu_subRN,    "cv_alu_subRN", RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_SI_SI_UQI, cvalu),
+RISCV_BUILTIN (cv_alu_subuRN,   "cv_alu_subuRN",RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI_UQI,  cvalu),
diff --git a/gcc/config/riscv/corev.md b/gcc/config/riscv/corev.md
index 65ce09ea6eb..1350bd4b81e 100644
--- a/gcc/config/riscv/corev.md
+++ b/gcc/config/riscv/corev.md
@@ -17,6 +17,15 @@
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.
 
+(define_c_enum "unspec" [
+
+  ;;CORE-V ALU
+  UNSPEC_CV_ALU_CLIP
+  UNSPEC_CV_ALU_CLIPR
+  UNSPEC_CV_ALU_CLIPU
+  UNSPEC_CV_ALU_CLIPUR
+])
+
 ;; XCVMAC extension.
 
 (define_insn "riscv_cv_mac_mac"
@@ -388,3 +397,297 @@
   "cv.machhsrn\t%0,%1,%2,%4"
   [(set_attr "type" "arith")
   (set_attr "mode" "SI")])
+
+;; XCVALU builtins
+
+(define_insn "riscv_cv_alu_slet"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (le:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.sle\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_sletu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (leu:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.sleu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_min"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (smin:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.min\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_minu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (umin:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.minu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_max"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (smax:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.max\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_maxu"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+    (umax:SI
+      (match_operand:SI 1 "register_operand" "r")
+      (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.maxu\t%0, %1, %2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_exths"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (sign_extend:SI
+     (truncate:HI
+       (match_operand:HI 1 "register_operand" "r"))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.exths\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_exthz"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (zero_extend:SI
+     (truncate:HI
+       (match_operand:HI 1 "register_operand" "r"))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.exthz\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_extbs"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (sign_extend:SI
+     (truncate:QI
+       (match_operand:QI 1 "register_operand" "r"))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.extbs\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_extbz"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+   (zero_extend:SI
+     (truncate:QI
+   (match_operand:QI 1 "register_operand" "r"))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "cv.extbz\t%0, %1"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_clip"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
+    UNSPEC_CV_ALU_CLIP))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.clip\t%0,%1,%X2
+  cv.clipr\t%0,%1,%2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_clipu"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+   (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+               (match_operand:SI 2 "immediate_register_operand" "CVP2,r")]
+    UNSPEC_CV_ALU_CLIPU))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.clipu\t%0,%1,%X2
+  cv.clipur\t%0,%1,%2"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_addN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (ashiftrt:SI
+      (plus:SI
+        (match_operand:SI 1 "register_operand" "r,0")
+        (match_operand:SI 2 "register_operand" "r,r"))
+      (and:SI (match_operand:QI 3 "csr_operand" "K,r")
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addn\t%0,%1,%2,%3
+  cv.addnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_adduN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (lshiftrt:SI
+      (plus:SI
+        (match_operand:SI 1 "register_operand" "r,0")
+        (match_operand:SI 2 "register_operand" "r,r"))
+      (and:SI (match_operand:QI 3 "csr_operand" "K,r")
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addun\t%0,%1,%2,%3
+  cv.addunr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_addRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (ashiftrt:SI
+      (plus:SI
+        (plus:SI
+          (match_operand:SI 1 "register_operand" "r,0")
+          (match_operand:SI 2 "register_operand" "r,r"))
+        (if_then_else (eq (match_operand:QI 3 "csr_operand" "K,r")
+                          (const_int 0))
+          (const_int 1)
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))))
+      (and:SI (match_dup 3)
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addrn\t%0,%1,%2,%3
+  cv.addrnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_adduRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (lshiftrt:SI
+      (plus:SI
+        (plus:SI
+          (match_operand:SI 1 "register_operand" "r,0")
+          (match_operand:SI 2 "register_operand" "r,r"))
+        (if_then_else (eq (match_operand:QI 3 "csr_operand" "K,r")
+                          (const_int 0))
+          (const_int 1)
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))))
+      (and:SI (match_dup 3)
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.addurn\t%0,%1,%2,%3
+  cv.addurnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (ashiftrt:SI
+      (minus:SI
+        (match_operand:SI 1 "register_operand" "r,0")
+        (match_operand:SI 2 "register_operand" "r,r"))
+      (and:SI (match_operand:QI 3 "csr_operand" "K,r")
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subn\t%0,%1,%2,%3
+  cv.subnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subuN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (lshiftrt:SI
+      (minus:SI
+        (match_operand:SI 1 "register_operand" "r,0")
+        (match_operand:SI 2 "register_operand" "r,r"))
+      (and:SI (match_operand:QI 3 "csr_operand" "K,r")
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subun\t%0,%1,%2,%3
+  cv.subunr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (ashiftrt:SI
+      (plus:SI
+        (minus:SI
+          (match_operand:SI 1 "register_operand" "r,0")
+          (match_operand:SI 2 "register_operand" "r,r"))
+        (if_then_else (eq (match_operand:QI 3 "csr_operand" "K,r")
+                          (const_int 0))
+          (const_int 1)
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))))
+      (and:SI (match_dup 3)
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.subrn\t%0,%1,%2,%3
+  cv.subrnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_alu_subuRN"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+    (lshiftrt:SI
+      (plus:SI
+        (minus:SI
+          (match_operand:SI 1 "register_operand" "r,0")
+          (match_operand:SI 2 "register_operand" "r,r"))
+        (if_then_else (eq (match_operand:QI 3 "csr_operand" "K,r")
+                          (const_int 0))
+          (const_int 1)
+          (ashift:SI (const_int 1)
+            (minus:QI (match_dup 3)
+                      (const_int 1)))))
+      (and:SI (match_dup 3)
+              (const_int 31))))]
+
+  "TARGET_XCVALU && !TARGET_64BIT"
+  "@
+  cv.suburn\t%0,%1,%2,%3
+  cv.suburnr\t%0,%2,%3"
+  [(set_attr "type" "arith")
+  (set_attr "mode" "SI")])
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 6b72a5f4e07..a37d035fa61 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -395,6 +395,11 @@
 	return true;
 })
 
+;; CORE-V Predicates:
+(define_predicate "immediate_register_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_code "const_int")))
+
 ;; Predicates for the V extension.
 (define_special_predicate "vector_length_operand"
   (ior (match_operand 0 "pmode_register_operand")
diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc
index 1f733337b82..fc3976f3ba1 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -127,6 +127,7 @@ AVAIL (hint_pause, (!0))
 
 // CORE-V AVAIL
 AVAIL (cvmac, TARGET_XCVMAC && !TARGET_64BIT)
+AVAIL (cvalu, TARGET_XCVALU && !TARGET_64BIT)
 
 /* Construct a riscv_builtin_description from the given arguments.
 
@@ -163,6 +164,8 @@ AVAIL (cvmac, TARGET_XCVMAC && !TARGET_64BIT)
 #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_QI intQI_type_node
+#define RISCV_ATYPE_HI intHI_type_node
 #define RISCV_ATYPE_SI intSI_type_node
 #define RISCV_ATYPE_VOID_PTR ptr_type_node
 
diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def
index 430a4c2d673..0d1e4dd061e 100644
--- a/gcc/config/riscv/riscv-ftypes.def
+++ b/gcc/config/riscv/riscv-ftypes.def
@@ -32,6 +32,10 @@ DEF_RISCV_FTYPE (1, (VOID, USI))
 DEF_RISCV_FTYPE (1, (VOID, VOID_PTR))
 DEF_RISCV_FTYPE (1, (USI, USI))
 DEF_RISCV_FTYPE (1, (UDI, UDI))
+DEF_RISCV_FTYPE (1, (USI, UQI))
+DEF_RISCV_FTYPE (1, (USI, UHI))
+DEF_RISCV_FTYPE (1, (SI, QI))
+DEF_RISCV_FTYPE (1, (SI, HI))
 DEF_RISCV_FTYPE (2, (USI, UQI, UQI))
 DEF_RISCV_FTYPE (2, (USI, UHI, UHI))
 DEF_RISCV_FTYPE (2, (USI, USI, USI))
@@ -40,6 +44,8 @@ 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 (2, (SI, USI, USI))
+DEF_RISCV_FTYPE (2, (SI, SI, SI))
 DEF_RISCV_FTYPE (3, (USI, USI, USI, UQI))
 DEF_RISCV_FTYPE (3, (USI, USI, USI, USI))
 DEF_RISCV_FTYPE (3, (SI, SI, SI, UQI))
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index d17139e945e..5990f76e57e 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -5670,6 +5670,13 @@ riscv_print_operand (FILE *file, rtx op, int letter)
 	output_addr_const (file, newop);
 	break;
       }
+    case 'X':
+      {
+	int ival = INTVAL (op) + 1;
+	rtx newop = GEN_INT (ctz_hwi (ival) + 1);
+	output_addr_const (file, newop);
+	break;
+      }
     default:
       switch (code)
 	{
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index f838f6ec55f..70d78151cee 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -409,6 +409,8 @@ int riscv_xcv_subext
 
 Mask(XCVMAC) Var(riscv_xcv_subext)
 
+Mask(XCVALU) Var(riscv_xcv_subext)
+
 TargetVariable
 int riscv_xthead_subext
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index d71397310df..eb665188caf 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -21792,6 +21792,100 @@ Generates the @code{cv.macsRN} machine instruction.
 Generates the @code{cv.machhsRN} machine instruction.
 @end deftypefn
 
+These built-in functions are available for the CORE-V ALU 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-miscellaneous-alu-builtins-xcvalu}
+
+@deftypefn {Built-in Function} {int} __builtin_riscv_cv_alu_slet (int32_t, int32_t)
+Generated assembler @code{cv.slet}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int} __builtin_riscv_cv_alu_sletu (uint32_t, uint32_t)
+Generated assembler @code{cv.sletu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_min (int32_t, int32_t)
+Generated assembler @code{cv.min}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_minu (uint32_t, uint32_t)
+Generated assembler @code{cv.minu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_max (int32_t, int32_t)
+Generated assembler @code{cv.max}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_tnt} __builtin_riscv_cv_alu_maxu (uint32_t, uint32_t)
+Generated assembler @code{cv.maxu}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_exths (int16_t)
+Generated assembler @code{cv.exths}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_exthz (uint16_t)
+Generated assembler @code{cv.exthz}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_extbs (int8_t)
+Generated assembler @code{cv.extbs}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_extbz (uint8_t)
+Generated assembler @code{cv.extbz}
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_clip (int32_t, uint32_t)
+Generated assembler @code{cv.clip} if the uint32_t operand is a constant and an exact power of 2.
+Generated assembler @code{cv.clipr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_clipu (uint32_t, uint32_t)
+Generated assembler @code{cv.clipu} if the uint32_t operand is a constant and an exact power of 2.
+Generated assembler @code{cv.clipur} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_addN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.addN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.addNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_adduN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.adduN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.adduNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_addRN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.addRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.addRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_adduRN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.adduRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.adduRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_subN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.subN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_subuN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.subuN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subuNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_alu_subRN (int32_t, int32_t, uint8_t)
+Generated assembler @code{cv.subRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subRNr} if  the it is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_alu_subuRN (uint32_t, uint32_t, uint8_t)
+Generated assembler @code{cv.subuRN} if the uint8_t operand is a constant and in the range 0 <= shft <= 31.
+Generated assembler @code{cv.subuRNr} if  the it is a register.
+@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 1e1e61a5d67..0cff2e8953a 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -2478,6 +2478,9 @@ Test system has an integer register width of 64 bits.
 @item cv_mac
 Test system has support for the CORE-V MAC extension.
 
+@item cv_alu
+Test system has support for the CORE-V ALU extension.
+
 @end table
 
 @subsubsection Other hardware attributes
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-compile.c b/gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
new file mode 100644
index 00000000000..57289bb10eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-compile.c
@@ -0,0 +1,252 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+#include <stdint.h>
+
+extern int d;
+extern int e;
+extern int f;
+
+void
+foo0(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, 0);
+  e = __builtin_riscv_cv_alu_addN (a, b, 7);
+  f = __builtin_riscv_cv_alu_addN (a, b, 31);
+}
+
+void
+foo1(int a, int b, int c)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, c);
+}
+
+void
+foo2(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_addRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_addRN (a, b, 31);
+}
+
+int
+foo3(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_addRN (a, b, c);
+}
+
+void
+foo4(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduN (a, b, 0);
+  e = __builtin_riscv_cv_alu_adduN (a, b, 7);
+  f = __builtin_riscv_cv_alu_adduN (a, b, 31);
+}
+
+int
+foo5(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_adduN (a, b, c);
+}
+
+void
+foo6(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_adduRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_adduRN (a, b, 31);
+}
+
+int
+foo7(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_adduRN (a, b, c);
+}
+
+int
+foo8(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clip (a, 15);
+}
+
+int
+foo9(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clip (a, 10);
+}
+
+int
+foo10(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clipu (a, 15);
+}
+
+int
+foo11(int a, int b)
+{
+  return __builtin_riscv_cv_alu_clipu (a, 10);
+}
+
+int
+foo12(int a)
+{
+  return __builtin_riscv_cv_alu_extbs (a);
+}
+
+int
+foo13(int a)
+{
+  return __builtin_riscv_cv_alu_extbz (a);
+}
+
+int
+foo14(int b)
+{
+  return __builtin_riscv_cv_alu_exths (b);
+}
+
+int
+foo15(int a)
+{
+  return __builtin_riscv_cv_alu_exthz (a);
+}
+
+int
+foo16(int a, int b)
+{
+  return __builtin_riscv_cv_alu_max (a, b);
+}
+
+int
+foo17(int a, int b)
+{
+  return __builtin_riscv_cv_alu_maxu (a, b);
+}
+
+int
+foo18(int a, int b)
+{
+  return __builtin_riscv_cv_alu_min (a, b);
+}
+
+int
+foo19(int a, int b)
+{
+  return __builtin_riscv_cv_alu_minu (a, b);
+}
+
+int
+foo20(int a, int b)
+{
+  return __builtin_riscv_cv_alu_slet (a, b);
+}
+
+int
+foo21(unsigned int a, unsigned int b)
+{
+  return __builtin_riscv_cv_alu_sletu (a, b);
+}
+
+void
+foo22(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subN (a, b, 31);
+}
+
+int
+foo23(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subN (a, b, c);
+}
+
+void
+foo24(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subRN (a, b, 31);
+}
+
+int
+foo25(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subRN (a, b, c);
+}
+
+void
+foo26(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subuN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subuN (a, b, 31);
+}
+
+int
+foo27(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subuN (a, b, c);
+}
+
+void
+foo28(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuRN (a, b, 0);
+  e = __builtin_riscv_cv_alu_subuRN (a, b, 7);
+  f = __builtin_riscv_cv_alu_subuRN (a, b, 31);
+}
+
+int
+foo29(int a, int b, int c)
+{
+  return __builtin_riscv_cv_alu_subuRN (a, b, c);
+}
+
+/* { dg-final { scan-assembler-times "cv\.addn\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 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\.addn\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\.addn\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\\.addnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addrn\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\.addrn\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\.addrn\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\\.addrnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addun\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 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\.addun\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\.addun\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\\.addunr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.addurn\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\.addurn\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\.addurn\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\\.addurnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.clip\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),5" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.clipr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.clipu\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),5" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.clipur\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.extbs\t" 1 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\\.extbz\t" 1 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\\.exths\t" 1 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\\.exthz\t" 1 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\\.max\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.maxu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.min\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.minu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.sle\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\\.sleu\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subn\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 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\.subn\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\.subn\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\\.subnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subrn\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\.subrn\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\.subrn\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\\.subrnr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.subun\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 { target { no-opts "-O1" no-opts "-O2" no-opts "-O3" no-opts "-Og" no-opts "-Oz" no-opts "-Os" } } } } */
+/* { dg-final { scan-assembler-times "cv\.subun\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\.subun\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\\.subunr\t" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.suburn\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\.suburn\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\.suburn\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\\.suburnr\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
new file mode 100644
index 00000000000..aa8610f4c2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
new file mode 100644
index 00000000000..12371b2c641
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addrn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_addRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
new file mode 100644
index 00000000000..3faad6c73c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addun.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
new file mode 100644
index 00000000000..39dc575b68e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-addurn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_adduRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
new file mode 100644
index 00000000000..a5ee231c74d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clip.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_clip (a, 4294967296); /* { dg-warning "overflow in conversion from \'long long int\' to \'int\' changes value from \'4294967296\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
new file mode 100644
index 00000000000..1ee11d2f600
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-clipu.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_clipu (a, 4294967296); /* { dg-warning "unsigned conversion from \'long long int\' to \'unsigned int\' changes value from \'4294967296\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
new file mode 100644
index 00000000000..91d6bd56672
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
new file mode 100644
index 00000000000..3c7e4ae63d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subrn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
new file mode 100644
index 00000000000..46218ea4451
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-subun.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
new file mode 100644
index 00000000000..f20378dd839
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile-suburn.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i_xcvalu -mabi=ilp32" } */
+
+extern int d;
+
+void
+foo(int a, int b)
+{
+  d = __builtin_riscv_cv_alu_subuRN (a, b, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'unsigned char\' changes value from \'65536\' to \'0\'" } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
new file mode 100644
index 00000000000..bbdb2d58c3f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-alu-fail-compile.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_alu } */
+/* { dg-options "-march=rv32i -mabi=ilp32" } */
+
+extern int d;
+
+int
+foo(int a, int b, int c)
+{
+    d += __builtin_riscv_cv_alu_slet (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_sletu (a, b);  /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_addN (a, b, 31);  /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_addRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_adduN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_adduRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_clip (a, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_clipu (a, 35); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_extbs (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_extbz (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_exths (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_exthz (a); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_min (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_minu (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_max (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_maxu (a, b); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subuN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+    d += __builtin_riscv_cv_alu_subuRN (a, b, 31); /* { dg-warning "implicit declaration of function" } */
+
+    return d;
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 498903557e5..adcdacbc771 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -12928,6 +12928,19 @@ proc check_effective_target_cv_mac { } {
     } "-march=rv32i_xcvmac" ]
 }
 
+# Return 1 if the CORE-V ALU extension is available.
+proc check_effective_target_cv_alu { } {
+    if { !([istarget riscv*-*-*]) } {
+         return 0
+     }
+    return [check_no_compiler_messages cv_alu object {
+        void foo (void)
+        {
+          asm ("cv.addn t0, t1, t2, 0");
+        }
+    } "-march=rv32i_xcvalu" ]
+}
+
 # Appends necessary Python flags to extra-tool-flags if Python.h is supported.
 # Otherwise, modifies dg-do-what.
 proc dg-require-python-h { args } {
-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v4 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions
  2023-10-11 12:06     ` [PATCH v4 " Mary Bennett
  2023-10-11 12:06       ` [PATCH v4 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
  2023-10-11 12:06       ` [PATCH v4 2/2] RISC-V: Add support for XCValu " Mary Bennett
@ 2023-10-11 13:49       ` Jeff Law
  2 siblings, 0 replies; 15+ messages in thread
From: Jeff Law @ 2023-10-11 13:49 UTC (permalink / raw)
  To: Mary Bennett, gcc-patches



On 10/11/23 06:06, Mary Bennett wrote:
> This patch series presents the comprehensive implementation of the MAC and ALU
> extension for CORE-V.
> 
> Tested with riscv-gnu-toolchain on binutils, ld, gas and gcc testsuites to
> ensure its correctness and compatibility with the existing codebase.
> However, your input, reviews, and suggestions are invaluable in making this
> extension even more robust.
> 
> The CORE-V builtins are described in the specification [1] and work can be
> found in the OpenHW group's Github repository [2].
> 
> [1] github.com/openhwgroup/core-v-sw/blob/master/specifications/corev-builtin-spec.md
> 
> [2] github.com/openhwgroup/corev-gcc
> 
> 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>
> 
>    RISC-V: Add support for XCValu extension in CV32E40P
>    RISC-V: Add support for XCVmac extension in CV32E40P
Per yesterday's discussion, I've pushed both rebased patches to the trunk.

Thanks!

jeff

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2023-10-11 13:49 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-19 15:07 [PATCH 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
2023-09-19 15:07 ` [PATCH 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
2023-09-19 15:07 ` [PATCH 2/2] RISC-V: Add support for XCValu " Mary Bennett
2023-09-23  9:04   ` Kito Cheng
2023-09-27 12:26 ` [PATCH v2 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
2023-09-27 12:26   ` [PATCH v2 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
2023-09-27 12:26   ` [PATCH v2 2/2] RISC-V: Add support for XCValu " Mary Bennett
2023-09-30 12:00   ` [PATCH v3 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Mary Bennett
2023-09-30 12:00     ` [PATCH v3 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
2023-09-30 12:00     ` [PATCH v3 2/2] RISC-V: Add support for XCValu " Mary Bennett
2023-10-10 14:52     ` [PATCH v3 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Kito Cheng
2023-10-11 12:06     ` [PATCH v4 " Mary Bennett
2023-10-11 12:06       ` [PATCH v4 1/2] RISC-V: Add support for XCVmac extension in CV32E40P Mary Bennett
2023-10-11 12:06       ` [PATCH v4 2/2] RISC-V: Add support for XCValu " Mary Bennett
2023-10-11 13:49       ` [PATCH v4 0/2] RISC-V: Support CORE-V XCVMAC and XCVALU extensions Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).