public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/1] RISC-V: Support CORE-V XCVBITMAIP extension
@ 2023-11-09 10:55 Mary Bennett
  2023-11-09 10:55 ` [PATCH 1/1] RISC-V: Add support for XCVbitmanip extension in CV32E40P Mary Bennett
  0 siblings, 1 reply; 4+ messages in thread
From: Mary Bennett @ 2023-11-09 10:55 UTC (permalink / raw)
  To: gcc-patches; +Cc: mary.bennett

This patch series presents the comprehensive implementation of the BITMANIP
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 XCVbitmanip extension in CV32E40P

 gcc/common/config/riscv/riscv-common.cc       |   2 +
 gcc/config/riscv/constraints.md               |   5 +
 gcc/config/riscv/corev.def                    |  13 +
 gcc/config/riscv/corev.md                     | 342 ++++++++++++++++++
 gcc/config/riscv/predicates.md                |  16 +
 gcc/config/riscv/riscv-builtins.cc            |   1 +
 gcc/config/riscv/riscv-ftypes.def             |   5 +
 gcc/config/riscv/riscv.opt                    |   2 +
 gcc/doc/extend.texi                           |  53 +++
 gcc/doc/sourcebuild.texi                      |   3 +
 .../riscv/cv-bitmanip-compile-bclr.c          |  27 ++
 .../riscv/cv-bitmanip-compile-bclrr.c         |  18 +
 .../riscv/cv-bitmanip-compile-bitrev.c        |  30 ++
 .../riscv/cv-bitmanip-compile-bset.c          |  27 ++
 .../riscv/cv-bitmanip-compile-bsetr.c         |  18 +
 .../riscv/cv-bitmanip-compile-clb.c           |  18 +
 .../riscv/cv-bitmanip-compile-cnt.c           |  18 +
 .../riscv/cv-bitmanip-compile-extract.c       |  27 ++
 .../riscv/cv-bitmanip-compile-extractr.c      |  18 +
 .../riscv/cv-bitmanip-compile-extractu.c      |  27 ++
 .../riscv/cv-bitmanip-compile-extractur.c     |  18 +
 .../riscv/cv-bitmanip-compile-ff1.c           |  18 +
 .../riscv/cv-bitmanip-compile-fl1.c           |  18 +
 .../riscv/cv-bitmanip-compile-insert.c        |  24 ++
 .../riscv/cv-bitmanip-compile-insertr.c       |  18 +
 .../riscv/cv-bitmanip-compile-ror.c           |  18 +
 .../riscv/cv-bitmanip-fail-compile-bclr.c     |  25 ++
 .../riscv/cv-bitmanip-fail-compile-bitrev.c   |  23 ++
 .../riscv/cv-bitmanip-fail-compile-bset.c     |  25 ++
 .../riscv/cv-bitmanip-fail-compile-extract.c  |  25 ++
 .../riscv/cv-bitmanip-fail-compile-extractu.c |  25 ++
 .../riscv/cv-bitmanip-fail-compile-insert.c   |  22 ++
 gcc/testsuite/lib/target-supports.exp         |  13 +
 33 files changed, 942 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bclr.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bclrr.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bitrev.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bset.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bsetr.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-clb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-cnt.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extract.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractr.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractur.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-ff1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-fl1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-insert.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-insertr.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-ror.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bclr.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bitrev.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bset.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-extract.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-extractu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-insert.c

-- 
2.34.1


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

* [PATCH 1/1] RISC-V: Add support for XCVbitmanip extension in CV32E40P
  2023-11-09 10:55 [PATCH 0/1] RISC-V: Support CORE-V XCVBITMAIP extension Mary Bennett
@ 2023-11-09 10:55 ` Mary Bennett
  2023-12-05 15:30   ` Kito Cheng
  0 siblings, 1 reply; 4+ messages in thread
From: Mary Bennett @ 2023-11-09 10:55 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 XCVbitmanip.
	* config/riscv/constraints.md: Likewise.
	* config/riscv/corev.def: Likewise.
	* config/riscv/corev.md: Likewise.
	* config/riscv/predicates.md: Likewise.
	* config/riscv/riscv-builtins.cc (AVAIL): Likewise.
	* config/riscv/riscv-ftypes.def: Likewise.
	* config/riscv/riscv.opt: Likewise.
	* doc/extend.texi: Add XCVbitmanip builtin documentation.
	* doc/sourcebuild.texi: Likewise.

gcc/testsuite/ChangeLog:
	* gcc.target/riscv/cv-bitmanip-compile-bclr.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-bclrr.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-bitrev.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-bset.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-bsetr.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-clb.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-cnt.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-extract.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-extractr.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-extractu.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-extractur.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-ff1.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-fl1.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-insert.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-insertr.c: New test.
	* gcc.target/riscv/cv-bitmanip-compile-ror.c: New test.
	* gcc.target/riscv/cv-bitmanip-fail-compile-bclr.c: New test.
	* gcc.target/riscv/cv-bitmanip-fail-compile-bitrev.c: New test.
	* gcc.target/riscv/cv-bitmanip-fail-compile-bset.c: New test.
	* gcc.target/riscv/cv-bitmanip-fail-compile-extract.c: New test.
	* gcc.target/riscv/cv-bitmanip-fail-compile-extractu.c: New test.
	* gcc.target/riscv/cv-bitmanip-fail-compile-insert.c: New test.
	* lib/target-supports.exp: Add proc for the XCVbitmanip extension.
---
 gcc/common/config/riscv/riscv-common.cc       |   2 +
 gcc/config/riscv/constraints.md               |   5 +
 gcc/config/riscv/corev.def                    |  13 +
 gcc/config/riscv/corev.md                     | 342 ++++++++++++++++++
 gcc/config/riscv/predicates.md                |  16 +
 gcc/config/riscv/riscv-builtins.cc            |   1 +
 gcc/config/riscv/riscv-ftypes.def             |   5 +
 gcc/config/riscv/riscv.opt                    |   2 +
 gcc/doc/extend.texi                           |  53 +++
 gcc/doc/sourcebuild.texi                      |   3 +
 .../riscv/cv-bitmanip-compile-bclr.c          |  27 ++
 .../riscv/cv-bitmanip-compile-bclrr.c         |  18 +
 .../riscv/cv-bitmanip-compile-bitrev.c        |  30 ++
 .../riscv/cv-bitmanip-compile-bset.c          |  27 ++
 .../riscv/cv-bitmanip-compile-bsetr.c         |  18 +
 .../riscv/cv-bitmanip-compile-clb.c           |  18 +
 .../riscv/cv-bitmanip-compile-cnt.c           |  18 +
 .../riscv/cv-bitmanip-compile-extract.c       |  27 ++
 .../riscv/cv-bitmanip-compile-extractr.c      |  18 +
 .../riscv/cv-bitmanip-compile-extractu.c      |  27 ++
 .../riscv/cv-bitmanip-compile-extractur.c     |  18 +
 .../riscv/cv-bitmanip-compile-ff1.c           |  18 +
 .../riscv/cv-bitmanip-compile-fl1.c           |  18 +
 .../riscv/cv-bitmanip-compile-insert.c        |  24 ++
 .../riscv/cv-bitmanip-compile-insertr.c       |  18 +
 .../riscv/cv-bitmanip-compile-ror.c           |  18 +
 .../riscv/cv-bitmanip-fail-compile-bclr.c     |  25 ++
 .../riscv/cv-bitmanip-fail-compile-bitrev.c   |  23 ++
 .../riscv/cv-bitmanip-fail-compile-bset.c     |  25 ++
 .../riscv/cv-bitmanip-fail-compile-extract.c  |  25 ++
 .../riscv/cv-bitmanip-fail-compile-extractu.c |  25 ++
 .../riscv/cv-bitmanip-fail-compile-insert.c   |  22 ++
 gcc/testsuite/lib/target-supports.exp         |  13 +
 33 files changed, 942 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bclr.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bclrr.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bitrev.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bset.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bsetr.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-clb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-cnt.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extract.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractr.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractur.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-ff1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-fl1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-insert.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-insertr.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-ror.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bclr.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bitrev.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bset.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-extract.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-extractu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-insert.c

diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 04631e007f0..9c20270d4aa 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -314,6 +314,7 @@ static const struct riscv_ext_version riscv_ext_version_table[] =
   {"xcvalu", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xcvelw", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xcvbi", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xcvbitmanip", ISA_SPEC_CLASS_NONE, 1, 0},
 
   {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1671,6 +1672,7 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
   {"xcvalu",        &gcc_options::x_riscv_xcv_subext, MASK_XCVALU},
   {"xcvelw",        &gcc_options::x_riscv_xcv_subext, MASK_XCVELW},
   {"xcvbi",         &gcc_options::x_riscv_xcv_subext, MASK_XCVBI},
+  {"xcvbitmanip",   &gcc_options::x_riscv_xcv_subext, MASK_XCVBITMANIP},
 
   {"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 718b4bd77df..113438b65a3 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -253,3 +253,8 @@
    A 5-bit signed immediate for CORE-V Immediate Branch."
   (and (match_code "const_int")
        (match_test "IN_RANGE (ival, -16, 15)")))
+
+(define_constraint "CV_bit_si10"
+  "A 10-bit unsigned immediate for CORE-V bitmanip."
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (ival, 0, 1023)")))
diff --git a/gcc/config/riscv/corev.def b/gcc/config/riscv/corev.def
index 3b9ec029d06..509f33b98f8 100644
--- a/gcc/config/riscv/corev.def
+++ b/gcc/config/riscv/corev.def
@@ -44,3 +44,16 @@ RISCV_BUILTIN (cv_alu_subuRN,   "cv_alu_subuRN",RISCV_BUILTIN_DIRECT, RISCV_USI_
 
 // XCVELW
 RISCV_BUILTIN (cv_elw_elw_si, "cv_elw_elw", RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_VOID_PTR, cvelw),
+
+// XCVBITMANIP
+RISCV_BUILTIN (cv_bitmanip_extract,     "cv_bitmanip_extract",     RISCV_BUILTIN_DIRECT, RISCV_SI_FTYPE_USI_UHI,         cvbitmanip),
+RISCV_BUILTIN (cv_bitmanip_extractu,    "cv_bitmanip_extractu",    RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_UHI,        cvbitmanip),
+RISCV_BUILTIN (cv_bitmanip_insert,      "cv_bitmanip_insert",      RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_UHI_USI,    cvbitmanip),
+RISCV_BUILTIN (cv_bitmanip_bclr,        "cv_bitmanip_bclr",        RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_UHI,        cvbitmanip),
+RISCV_BUILTIN (cv_bitmanip_bset,        "cv_bitmanip_bset",        RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_UHI,        cvbitmanip),
+RISCV_BUILTIN (cv_bitmanip_ff1,         "cv_bitmanip_ff1",         RISCV_BUILTIN_DIRECT, RISCV_UQI_FTYPE_USI,            cvbitmanip),
+RISCV_BUILTIN (cv_bitmanip_fl1,         "cv_bitmanip_fl1",         RISCV_BUILTIN_DIRECT, RISCV_UQI_FTYPE_USI,            cvbitmanip),
+RISCV_BUILTIN (cv_bitmanip_clb,         "cv_bitmanip_clb",         RISCV_BUILTIN_DIRECT, RISCV_UQI_FTYPE_USI,            cvbitmanip),
+RISCV_BUILTIN (cv_bitmanip_cnt,         "cv_bitmanip_cnt",         RISCV_BUILTIN_DIRECT, RISCV_UQI_FTYPE_USI,            cvbitmanip),
+RISCV_BUILTIN (cv_bitmanip_ror,         "cv_bitmanip_ror",         RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_USI,        cvbitmanip),
+RISCV_BUILTIN (cv_bitmanip_bitrev,      "cv_bitmanip_bitrev",      RISCV_BUILTIN_DIRECT, RISCV_USI_FTYPE_USI_UQI_UQI,    cvbitmanip),
diff --git a/gcc/config/riscv/corev.md b/gcc/config/riscv/corev.md
index 7d7b952d817..e7d4ad1760c 100644
--- a/gcc/config/riscv/corev.md
+++ b/gcc/config/riscv/corev.md
@@ -27,6 +27,25 @@
 
   ;;CORE-V EVENT LOAD
   UNSPECV_CV_ELW
+
+  ;;CORE-V BITMANIP
+  UNSPEC_CV_BITMANIP_EXTRACT
+  UNSPEC_CV_BITMANIP_EXTRACT_INSN
+  UNSPEC_CV_BITMANIP_EXTRACTR_INSN
+  UNSPEC_CV_BITMANIP_EXTRACTU
+  UNSPEC_CV_BITMANIP_EXTRACTU_INSN
+  UNSPEC_CV_BITMANIP_EXTRACTUR_INSN
+  UNSPEC_CV_BITMANIP_INSERT
+  UNSPEC_CV_BITMANIP_INSERT_INSN
+  UNSPEC_CV_BITMANIP_INSERTR_INSN
+  UNSPEC_CV_BITMANIP_BCLR
+  UNSPEC_CV_BITMANIP_BCLR_INSN
+  UNSPEC_CV_BITMANIP_BCLRR_INSN
+  UNSPEC_CV_BITMANIP_BSET
+  UNSPEC_CV_BITMANIP_BSET_INSN
+  UNSPEC_CV_BITMANIP_BSETR_INSN
+  UNSPEC_CV_BITMANIP_BITREV
+  UNSPEC_CV_BITMANIP_FL1
 ])
 
 ;; XCVMAC extension.
@@ -720,3 +739,326 @@
   "cv.b%C1imm\t%2,%3,%0"
   [(set_attr "type" "branch")
    (set_attr "mode" "none")])
+
+;; XCVBITMANIP builtins
+(define_insn "riscv_cv_bitmanip_extract_insn"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+                   (match_operand:QI 2 "const_csr_operand" "K")
+                   (match_operand:QI 3 "const_csr_operand" "K")]
+         UNSPEC_CV_BITMANIP_EXTRACT_INSN))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.extract\t%0,%1,%3,%2"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_bitmanip_extractr_insn"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+                   (match_operand:HI 2 "register_UHI_operand" "r")]
+         UNSPEC_CV_BITMANIP_EXTRACTR_INSN))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.extractr\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+;; Since the expand instruction requires operand 2 to be broken into two smaller operands,
+;; a block of c code must be used to ensure the correct values are passed. Hence a define_expand
+;; function is used.
+(define_expand "riscv_cv_bitmanip_extract"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+                   (match_operand:HI 2 "bit_extract_operand" "CV_bit_si10,r")]
+         UNSPEC_CV_BITMANIP_EXTRACT))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+{
+  if ((GET_CODE (operands[2]) == CONST_INT) &&
+    (INTVAL (operands[2]) <= 1023) && (INTVAL (operands[2]) >= 0))
+  {
+    int op2_hi = (int)(INTVAL (operands[2]) >> 5);
+    int op2_lo = INTVAL (operands[2]) - (op2_hi * 32);
+    rtx t3 = GEN_INT (op2_lo);
+    rtx t4 = GEN_INT (op2_hi);
+    emit_insn (gen_riscv_cv_bitmanip_extract_insn (operands[0], operands[1], t3, t4));
+    DONE;
+  }
+  else if ((GET_CODE (operands[2]) == REG) ||
+    (GET_CODE (operands[2]) == SUBREG))
+  {
+    emit_insn (gen_riscv_cv_bitmanip_extractr_insn (operands[0], operands[1], operands[2]));
+    DONE;
+  }
+  FAIL;
+})
+
+(define_insn "riscv_cv_bitmanip_extractu_insn"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+                   (match_operand:QI 2 "const_csr_operand" "K")
+                   (match_operand:QI 3 "const_csr_operand" "K")]
+         UNSPEC_CV_BITMANIP_EXTRACTU_INSN))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.extractu\t%0,%1,%3,%2"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_bitmanip_extractur_insn"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+                   (match_operand:HI 2 "register_UHI_operand" "r")]
+         UNSPEC_CV_BITMANIP_EXTRACTUR_INSN))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.extractur\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_expand "riscv_cv_bitmanip_extractu"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+                   (match_operand:HI 2 "bit_extract_operand" "CV_bit_si10,r")]
+         UNSPEC_CV_BITMANIP_EXTRACTU))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+{
+  if ((GET_CODE (operands[2]) == CONST_INT) &&
+    (INTVAL (operands[2]) <= 1023))
+  {
+    int op2_hi = (int)(INTVAL (operands[2]) >> 5);
+    int op2_lo = INTVAL (operands[2]) - (op2_hi * 32);
+    rtx t3 = GEN_INT (op2_lo);
+    rtx t4 = GEN_INT (op2_hi);
+    emit_insn (gen_riscv_cv_bitmanip_extractu_insn (operands[0], operands[1], t3, t4));
+    DONE;
+  }
+  else if ((GET_CODE (operands[2]) == REG) ||
+    (GET_CODE (operands[2]) == SUBREG))
+  {
+    emit_insn (gen_riscv_cv_bitmanip_extractur_insn (operands[0], operands[1], operands[2]));
+    DONE;
+  }
+  FAIL;
+})
+
+(define_insn "riscv_cv_bitmanip_insert_insn"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+                   (match_operand:QI 2 "const_csr_operand" "K")
+                   (match_operand:QI 3 "const_csr_operand" "K")
+                   (match_operand:SI 4 "register_operand" "0")]
+         UNSPEC_CV_BITMANIP_INSERT_INSN))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.insert\t%0,%1,%3,%2"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_bitmanip_insertr_insn"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+                   (match_operand:HI 2 "register_UHI_operand" "r")
+                   (match_operand:SI 3 "register_operand" "0")]
+         UNSPEC_CV_BITMANIP_INSERTR_INSN))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.insertr\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_expand "riscv_cv_bitmanip_insert"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+                   (match_operand:HI 2 "bit_extract_operand" "CV_bit_si10,r")
+                   (match_operand:SI 3 "register_operand" "0,0")]
+         UNSPEC_CV_BITMANIP_INSERT))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+{
+  if ((GET_CODE (operands[2]) == CONST_INT) &&
+    (INTVAL (operands[2]) <= 1023))
+  {
+    int op2_hi = (int)(INTVAL (operands[2]) >> 5);
+    int op2_lo = INTVAL (operands[2]) - (op2_hi * 32);
+    if ((op2_hi + op2_lo) >= 32)
+      FAIL;
+    rtx t3 = GEN_INT (op2_lo);
+    rtx t4 = GEN_INT (op2_hi);
+    emit_insn (gen_riscv_cv_bitmanip_insert_insn (operands[0], operands[1], t3, t4, operands[3]));
+    DONE;
+  }
+  else if ((GET_CODE (operands[2]) == REG) ||
+    (GET_CODE (operands[2]) == SUBREG))
+  {
+    emit_insn (gen_riscv_cv_bitmanip_insertr_insn (operands[0], operands[1], operands[2], operands[3]));
+    DONE;
+  }
+  FAIL;
+})
+
+(define_insn "riscv_cv_bitmanip_bclr_insn"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+                   (match_operand:QI 2 "const_csr_operand" "K")
+                   (match_operand:QI 3 "const_csr_operand" "K")]
+         UNSPEC_CV_BITMANIP_BCLR_INSN))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.bclr\t%0,%1,%3,%2"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_bitmanip_bclrr_insn"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+                   (match_operand:HI 2 "register_UHI_operand" "r")]
+         UNSPEC_CV_BITMANIP_BCLRR_INSN))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.bclrr\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_expand "riscv_cv_bitmanip_bclr"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+                   (match_operand:HI 2 "bit_extract_operand" "CV_bit_si10,r")]
+         UNSPEC_CV_BITMANIP_BCLR))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+{
+  if ((GET_CODE (operands[2]) == CONST_INT) &&
+    (INTVAL (operands[2]) <= 1023))
+  {
+    int op2_hi = (int)(INTVAL (operands[2]) >> 5);
+    int op2_lo = INTVAL (operands[2]) - (op2_hi * 32);
+    rtx t3 = GEN_INT (op2_lo);
+    rtx t4 = GEN_INT (op2_hi);
+    emit_insn (gen_riscv_cv_bitmanip_bclr_insn (operands[0], operands[1], t3, t4));
+    DONE;
+  }
+  else if ((GET_CODE (operands[2]) == REG) ||
+    (GET_CODE (operands[2]) == SUBREG))
+  {
+    emit_insn (gen_riscv_cv_bitmanip_bclrr_insn (operands[0], operands[1], operands[2]));
+    DONE;
+  }
+  FAIL;
+})
+
+(define_insn "riscv_cv_bitmanip_bset_insn"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+                   (match_operand:QI 2 "const_csr_operand" "K")
+                   (match_operand:QI 3 "const_csr_operand" "K")]
+         UNSPEC_CV_BITMANIP_BSET_INSN))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.bset\t%0,%1,%3,%2"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_bitmanip_bsetr_insn"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+                   (match_operand:HI 2 "register_UHI_operand" "r")]
+         UNSPEC_CV_BITMANIP_BSETR_INSN))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.bsetr\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_expand "riscv_cv_bitmanip_bset"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")
+                   (match_operand:HI 2 "bit_extract_operand" "CV_bit_si10,r")]
+         UNSPEC_CV_BITMANIP_BSET))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+{
+  if ((GET_CODE (operands[2]) == CONST_INT) &&
+    (INTVAL (operands[2]) <= 1023))
+  {
+    int op2_hi = (int)(INTVAL (operands[2]) >> 5);
+    int op2_lo = INTVAL (operands[2]) - (op2_hi * 32);
+    rtx t3 = GEN_INT (op2_lo);
+    rtx t4 = GEN_INT (op2_hi);
+    emit_insn (gen_riscv_cv_bitmanip_bset_insn (operands[0], operands[1], t3, t4));
+    DONE;
+  }
+  else if ((GET_CODE (operands[2]) == REG) ||
+    (GET_CODE (operands[2]) == SUBREG))
+  {
+    emit_insn (gen_riscv_cv_bitmanip_bsetr_insn (operands[0], operands[1], operands[2]));
+    DONE;
+  }
+  FAIL;
+})
+
+(define_insn "riscv_cv_bitmanip_ff1"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (if_then_else (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0))
+                      (const_int 32)
+                      (minus:SI (ffs:SI (match_dup 1))
+                                (const_int 1))))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.ff1\t%0,%1"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_bitmanip_fl1"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (unspec:QI [(match_operand:SI 1 "register_operand" "r")]
+         UNSPEC_CV_BITMANIP_FL1))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.fl1\t%0,%1"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_bitmanip_clb"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (if_then_else (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0))
+                      (const_int 0)
+                      (truncate:QI (clrsb:SI (match_dup 1)))))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.clb\t%0,%1"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_bitmanip_cnt"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+        (truncate:QI (popcount:SI (match_operand:SI 1 "register_operand" "r"))))]
+ 
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.cnt\t%0,%1"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_bitmanip_ror"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (rotatert:SI (match_operand:SI 1 "register_operand" "r")
+                     (match_operand:SI 2 "register_operand" "r")))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.ror\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
+
+(define_insn "riscv_cv_bitmanip_bitrev"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+                    (match_operand:QI 2 "const_csr_operand" "K")
+                    (match_operand:QI 3 "const_int2_operand" "D03")]
+         UNSPEC_CV_BITMANIP_BITREV))]
+
+  "TARGET_XCVBITMANIP && !TARGET_64BIT"
+  "cv.bitrev\t%0,%1,%3,%2"
+  [(set_attr "type" "bitmanip")
+  (set_attr "mode" "SI")])
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 69a6319c2c8..2938dc6c9c3 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -404,6 +404,22 @@
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), -16, 15)")))
 
+(define_predicate "const_int10_operand"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (INTVAL (op), 0, 1023)")))
+
+(define_predicate "register_UHI_operand"
+  (and (match_code "reg,subreg")
+       (match_test "GET_MODE (op) == HImode")))
+
+(define_predicate "bit_extract_operand"
+  (ior (match_operand 0 "const_int10_operand")
+       (match_operand 0 "register_UHI_operand")))
+
+(define_predicate "const_int2_operand"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (INTVAL (op), 0, 3)")))
+
 ;; 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 5ee11ebe3bc..68633ae705f 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -129,6 +129,7 @@ AVAIL (hint_pause, (!0))
 AVAIL (cvmac, TARGET_XCVMAC && !TARGET_64BIT)
 AVAIL (cvalu, TARGET_XCVALU && !TARGET_64BIT)
 AVAIL (cvelw, TARGET_XCVELW && !TARGET_64BIT)
+AVAIL (cvbitmanip, TARGET_XCVBITMANIP && !TARGET_64BIT)
 
 /* Construct a riscv_builtin_description from the given arguments.
 
diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def
index 3e7d5c69503..8dd86067309 100644
--- a/gcc/config/riscv/riscv-ftypes.def
+++ b/gcc/config/riscv/riscv-ftypes.def
@@ -35,10 +35,13 @@ 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, (UQI, USI))
 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, (SI, USI, UHI))
+DEF_RISCV_FTYPE (2, (USI, USI, UHI))
 DEF_RISCV_FTYPE (2, (USI, USI, USI))
 DEF_RISCV_FTYPE (2, (UDI, UQI, UQI))
 DEF_RISCV_FTYPE (2, (UDI, UHI, UHI))
@@ -50,6 +53,8 @@ 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))
+DEF_RISCV_FTYPE (3, (USI, USI, UHI, USI))
+DEF_RISCV_FTYPE (3, (USI, USI, UQI, 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.opt b/gcc/config/riscv/riscv.opt
index d06c0f8f416..576ec39a2ea 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -415,6 +415,8 @@ Mask(XCVELW) Var(riscv_xcv_subext)
 
 Mask(XCVBI) Var(riscv_xcv_subext)
 
+Mask(XCVBITMANIP) Var(riscv_xcv_subext)
+
 TargetVariable
 int riscv_xthead_subext
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index b890acccac1..9ec17bbab89 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -21978,6 +21978,59 @@ architecture. For more information on CORE-V ELW builtins, please see
 Generated assembler @code{cv.elw}
 @end deftypefn
 
+These built-in functions are available for the CORE-V bit manipulation 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#pulp-bit-manipulation-builtins-for-32-bit-cores}
+
+@deftypefn {Built-in Function} {int32_t} __builtin_riscv_cv_bitmanip_extract (uint32_t, uint16_t)
+Generated assembler @code{cv.extract} if the uint16_t operand is a constant. Generated assembler
+@code{cv.extractr} if the uint16_t operand is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_bitmanip_extractu (uint32_t, uint16_t)
+Generated assembler @code{cv.extractu} if the uint16_t operand is a constant. Generated assembler
+@code{cv.extractur} if the uint16_t operand is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_bitmanip_insert (uint32_t, uint16_t, uint32_t)
+Generated assembler @code{cv.insert} if the uint16_t operand is a constant. Generated assembler
+@code{cv.insertr} if the uint16_t operand is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_bitmanip_bclr (uint32_t, uint16_t)
+Generated assembler @code{cv.bclr} if the uint16_t operand is a constant. Generated assembler
+@code{cv.bclrr} if the uint16_t operand is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_bitmanip_bset (uint32_t, uint16_t)
+Generated assembler @code{cv.bset} if the uint16_t operand is a constant. Generated assembler
+@code{cv.bsetr} if the uint16_t operand is a register.
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint8_t} __builtin_riscv_cv_bitmanip_ff1 (uint32_t)
+Generated assembler @code{cv.ff1}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint8_t} __builtin_riscv_cv_bitmanip_fl1 (uint32_t)
+Generated assembler @code{cv.fl1}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint8_t} __builtin_riscv_cv_bitmanip_clb (uint32_t)
+Generated assembler @code{cv.clb}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint8_t} __builtin_riscv_cv_bitmanip_cnt (uint32_t)
+Generated assembler @code{cv.cnt}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_bitmanip_ror (uint32_t, uint32_t)
+Generated assembler @code{cv.ror}
+@end deftypefn
+
+@deftypefn {Built-in Function} {uint32_t} __builtin_riscv_cv_bitmanip_bitrev (uint32_t, uint8_t, uint8_t)
+Generated assembler @code{cv.bitrev}
+@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 6fee1144238..85e219a7f8a 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -2487,6 +2487,9 @@ Test system has support for the CORE-V ELW extension.
 @item cv_bi
 Test system has support for the CORE-V BI extension.
 
+@item cv_bitmanip
+Test system has support for the CORE-V BITMANIP extension.
+
 @end table
 
 @subsubsection Other hardware attributes
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bclr.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bclr.c
new file mode 100644
index 00000000000..40903b1470f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bclr.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+extern uint32_t res4;
+
+uint32_t
+foo (uint32_t a)
+{
+  res1 = __builtin_riscv_cv_bitmanip_bclr (a, 200);
+  res2 = __builtin_riscv_cv_bitmanip_bclr (a, 0);
+  res3 = __builtin_riscv_cv_bitmanip_bclr (a, 31);
+  res4 = __builtin_riscv_cv_bitmanip_bclr (a, 1023);
+
+  return res1 + res2 + res3 + res4;
+}
+
+/* { dg-final { scan-assembler-times "cv\.bclr\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),6,8" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.bclr\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0,0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.bclr\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0,31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.bclr\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31,31" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bclrr.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bclrr.c
new file mode 100644
index 00000000000..211a76a470e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bclrr.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1;
+
+uint32_t
+foo (uint32_t a, uint16_t b)
+{
+  res1 = __builtin_riscv_cv_bitmanip_bclr (a, b);
+
+  return res1;
+}
+
+/* { dg-final { scan-assembler-times "cv\.bclrr\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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bitrev.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bitrev.c
new file mode 100644
index 00000000000..89af9eacbb2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bitrev.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+extern uint32_t res4;
+extern uint32_t res5;
+
+uint32_t
+foo (uint32_t a)
+{
+  res1 = __builtin_riscv_cv_bitmanip_bitrev (a, 20, 2);
+  res2 = __builtin_riscv_cv_bitmanip_bitrev (a, 0, 0);
+  res3 = __builtin_riscv_cv_bitmanip_bitrev (a, 31, 0);
+  res4 = __builtin_riscv_cv_bitmanip_bitrev (a, 0, 3);
+  res5 = __builtin_riscv_cv_bitmanip_bitrev (a, 31, 3);
+
+  return res1 + res2 + res3 + res4 + res5;
+}
+
+/* { dg-final { scan-assembler-times "cv\.bitrev\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),2,20" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.bitrev\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0,0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.bitrev\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0,31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.bitrev\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),3,0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.bitrev\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),3,31" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bset.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bset.c
new file mode 100644
index 00000000000..fbd13fc7c52
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bset.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+extern uint32_t res4;
+
+uint32_t
+foo (uint32_t a)
+{
+  res1 = __builtin_riscv_cv_bitmanip_bset (a, 200);
+  res2 = __builtin_riscv_cv_bitmanip_bset (a, 0);
+  res3 = __builtin_riscv_cv_bitmanip_bset (a, 31);
+  res4 = __builtin_riscv_cv_bitmanip_bset (a, 1023);
+
+  return res1 + res2 + res3 + res4;
+}
+
+/* { dg-final { scan-assembler-times "cv\.bset\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),6,8" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.bset\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0,0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.bset\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0,31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.bset\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31,31" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bsetr.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bsetr.c
new file mode 100644
index 00000000000..6e3790a9e91
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-bsetr.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1;
+
+uint32_t
+foo (uint32_t a, uint16_t b)
+{
+  res1 = __builtin_riscv_cv_bitmanip_bset (a, b);
+
+  return res1;
+}
+
+/* { dg-final { scan-assembler-times "cv\.bsetr\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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-clb.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-clb.c
new file mode 100644
index 00000000000..34a2784a6af
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-clb.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint8_t res1;
+
+uint8_t
+foo (uint32_t a)
+{
+  res1 = __builtin_riscv_cv_bitmanip_clb (a);
+
+  return res1;
+}
+
+/* { dg-final { scan-assembler-times "cv\.clb\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-cnt.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-cnt.c
new file mode 100644
index 00000000000..dd9398c45c1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-cnt.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint8_t res1;
+
+uint8_t
+foo (uint32_t a)
+{
+  res1 = __builtin_riscv_cv_bitmanip_cnt (a);
+
+  return res1;
+}
+
+/* { dg-final { scan-assembler-times "cv\.cnt\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extract.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extract.c
new file mode 100644
index 00000000000..abbf1130510
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extract.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern int32_t res1;
+extern int32_t res2;
+extern int32_t res3;
+extern int32_t res4;
+
+int32_t
+foo (int32_t a)
+{
+  res1 = __builtin_riscv_cv_bitmanip_extract (a, 200);
+  res2 = __builtin_riscv_cv_bitmanip_extract (a, 0);
+  res3 = __builtin_riscv_cv_bitmanip_extract (a, 31);
+  res4 = __builtin_riscv_cv_bitmanip_extract (a, 1023);
+
+  return res1 + res2 + res3 + res4;
+}
+
+/* { dg-final { scan-assembler-times "cv\.extract\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),6,8" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.extract\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0,0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.extract\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0,31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.extract\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31,31" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractr.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractr.c
new file mode 100644
index 00000000000..3b935c53ac5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractr.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern int32_t res1;
+
+int32_t
+foo (int32_t a, uint16_t b)
+{
+  res1 = __builtin_riscv_cv_bitmanip_extract (a, b);
+
+  return res1;
+}
+
+/* { dg-final { scan-assembler-times "cv\.extractr\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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractu.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractu.c
new file mode 100644
index 00000000000..95ea0cc551e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractu.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+extern uint32_t res4;
+
+uint32_t
+foo (uint32_t a)
+{
+  res1 = __builtin_riscv_cv_bitmanip_extractu (a, 200);
+  res2 = __builtin_riscv_cv_bitmanip_extractu (a, 0);
+  res3 = __builtin_riscv_cv_bitmanip_extractu (a, 31);
+  res4 = __builtin_riscv_cv_bitmanip_extractu (a, 1023);
+
+  return res1 + res2 + res3 + res4;
+}
+
+/* { dg-final { scan-assembler-times "cv\.extractu\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),6,8" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.extractu\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0,0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.extractu\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0,31" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.extractu\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),31,31" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractur.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractur.c
new file mode 100644
index 00000000000..742803ecc19
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-extractur.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1;
+
+uint32_t
+foo (uint32_t a, uint16_t b)
+{
+  res1 = __builtin_riscv_cv_bitmanip_extractu (a, b);
+
+  return res1;
+}
+
+/* { dg-final { scan-assembler-times "cv\.extractur\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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-ff1.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-ff1.c
new file mode 100644
index 00000000000..eab4e4df7f7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-ff1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint8_t res1;
+
+uint8_t
+foo (uint32_t a)
+{
+  res1 = __builtin_riscv_cv_bitmanip_ff1 (a);
+
+  return res1;
+}
+
+/* { dg-final { scan-assembler-times "cv\.ff1\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-fl1.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-fl1.c
new file mode 100644
index 00000000000..2ea8686d2e2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-fl1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint8_t res1;
+
+uint8_t
+foo (uint32_t a)
+{
+  res1 = __builtin_riscv_cv_bitmanip_fl1 (a);
+
+  return res1;
+}
+
+/* { dg-final { scan-assembler-times "cv\.fl1\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\)" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-insert.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-insert.c
new file mode 100644
index 00000000000..de58df9e3f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-insert.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+
+uint32_t
+foo (uint32_t a, uint32_t b)
+{
+  res1 = __builtin_riscv_cv_bitmanip_insert (a, 200, b);
+  res2 = __builtin_riscv_cv_bitmanip_insert (a, 0, b);
+  res3 = __builtin_riscv_cv_bitmanip_insert (a, 31, b);
+
+  return res1 + res2 + res3;
+}
+
+/* { dg-final { scan-assembler-times "cv\.insert\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),6,8" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.insert\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0,0" 1 } } */
+/* { dg-final { scan-assembler-times "cv\.insert\t\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),\(\?\:t\[0-6\]\|a\[0-7\]\|s\[1-11\]\),0,31" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-insertr.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-insertr.c
new file mode 100644
index 00000000000..9b67c64ccd0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-insertr.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1;
+
+uint32_t
+foo (uint32_t a, uint16_t b, uint32_t c)
+{
+  res1 = __builtin_riscv_cv_bitmanip_insert (a, b, c);
+
+  return res1;
+}
+
+/* { dg-final { scan-assembler-times "cv\.insertr\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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-ror.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-ror.c
new file mode 100644
index 00000000000..67de86306bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-compile-ror.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1;
+
+uint32_t
+foo (uint32_t a, uint32_t b)
+{
+  res1 = __builtin_riscv_cv_bitmanip_ror (a, b);
+
+  return res1;
+}
+
+/* { dg-final { scan-assembler-times "cv\.ror\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 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bclr.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bclr.c
new file mode 100644
index 00000000000..112cb436298
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bclr.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1, res2, res3, res4, res5, res6;
+
+uint32_t
+foo (void)
+{
+  res1 = __builtin_riscv_cv_bitmanip_bclr (648, -1);
+  res2 = __builtin_riscv_cv_bitmanip_bclr (648, 1);
+  res3 = __builtin_riscv_cv_bitmanip_bclr (648, 4);
+  res4 = __builtin_riscv_cv_bitmanip_bclr (684, 1023);
+  res5 = __builtin_riscv_cv_bitmanip_bclr (648, 1024);
+  res6 =  __builtin_riscv_cv_bitmanip_bclr (648, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'short unsigned int\' changes value from \'65536\' to \'0\'" "" { target *-*-* } } */
+
+  return res1 + res2 + res3 + res4 + res5 + res6;
+}
+
+/* { dg-final { scan-assembler-times "cv\.bclr\t" 4 } } */
+/* { dg-final { scan-assembler-times "cv\.bclrr\t" 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bitrev.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bitrev.c
new file mode 100644
index 00000000000..33650dd2e2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bitrev.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1;
+extern uint32_t res2;
+extern uint32_t res3;
+extern uint32_t res4;
+
+uint32_t
+foo (void)
+{
+  res1 = __builtin_riscv_cv_bitmanip_bitrev (648, 0, -1); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res2 = __builtin_riscv_cv_bitmanip_bitrev (648, -1, 0); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res3 = __builtin_riscv_cv_bitmanip_bitrev (648, 21, 4); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+  res4 = __builtin_riscv_cv_bitmanip_bitrev (648, 32, 2); /* { dg-error "invalid argument to built-in function" "" { target *-*-* } } */
+
+  return res1+res2+res3+res4;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bset.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bset.c
new file mode 100644
index 00000000000..1cb3dd95f95
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-bset.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1, res2, res3, res4, res5, res6;
+
+uint32_t
+foo (void)
+{
+  res1 = __builtin_riscv_cv_bitmanip_bset (648, -1);
+  res2 = __builtin_riscv_cv_bitmanip_bset (648, 1);
+  res3 = __builtin_riscv_cv_bitmanip_bset (648, 4);
+  res4 = __builtin_riscv_cv_bitmanip_bset (648, 1023);
+  res5 = __builtin_riscv_cv_bitmanip_bset (648, 1024);
+  res6 =  __builtin_riscv_cv_bitmanip_bset (648, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'short unsigned int\' changes value from \'65536\' to \'0\'" "" { target *-*-* } } */
+
+  return res1 + res2 + res3 + res4 + res5 + res6;
+}
+
+/* { dg-final { scan-assembler-times "cv\.bset\t" 4 } } */
+/* { dg-final { scan-assembler-times "cv\.bsetr\t" 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-extract.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-extract.c
new file mode 100644
index 00000000000..b7d0363c983
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-extract.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1, res2, res3, res4, res5, res6;
+
+uint32_t
+foo (void)
+{
+  res1 = __builtin_riscv_cv_bitmanip_extract (648, -1);
+  res2 = __builtin_riscv_cv_bitmanip_extract (648, 1);
+  res3 = __builtin_riscv_cv_bitmanip_extract (648, 230);
+  res4 = __builtin_riscv_cv_bitmanip_extract (648, 1023);
+  res5 = __builtin_riscv_cv_bitmanip_extract (648, 1024);
+  res6 =  __builtin_riscv_cv_bitmanip_extract (648, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'short unsigned int\' changes value from \'65536\' to \'0\'" "" { target *-*-* } } */
+
+  return res1 + res2 + res3 + res4 + res5 + res6;
+}
+
+/* { dg-final { scan-assembler-times "cv\.extract\t" 4 } } */
+/* { dg-final { scan-assembler-times "cv\.extractr\t" 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-extractu.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-extractu.c
new file mode 100644
index 00000000000..4ac9be394d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-extractu.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1, res2, res3, res4, res5, res6;
+
+uint32_t
+foo (void)
+{
+  res1 = __builtin_riscv_cv_bitmanip_extractu (648, -1);
+  res2 = __builtin_riscv_cv_bitmanip_extractu (648, 1);
+  res3 = __builtin_riscv_cv_bitmanip_extractu (648, 230);
+  res4 = __builtin_riscv_cv_bitmanip_extractu (648, 1023);
+  res5 = __builtin_riscv_cv_bitmanip_extractu (648, 1024);
+  res6 =  __builtin_riscv_cv_bitmanip_extractu (648, 65536); /* { dg-warning "unsigned conversion from \'int\' to \'short unsigned int\' changes value from \'65536\' to \'0\'" "" { target *-*-* } } */
+
+  return res1 + res2 + res3 + res4 + res5 + res6;
+}
+
+/* { dg-final { scan-assembler-times "cv\.extractu\t" 4 } } */
+/* { dg-final { scan-assembler-times "cv\.extractur\t" 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-insert.c b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-insert.c
new file mode 100644
index 00000000000..d5d1ea6dd37
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/cv-bitmanip-fail-compile-insert.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target cv_bitmanip } */
+/* { dg-options "-march=rv32i_xcvbitmanip -mabi=ilp32" } */
+/* { dg-skip-if "Skip LTO tests of builtin compilation" { *-*-* } { "-flto" } } */
+
+#include <stdint.h>
+#include <stdio.h>
+
+extern uint32_t res1, res2, res3, res4, res5, res6;
+
+uint32_t
+foo (void)
+{
+  res1 = __builtin_riscv_cv_bitmanip_insert (648, -1, 645);
+  res2 = __builtin_riscv_cv_bitmanip_insert (648, 1, 645);
+  res3 = __builtin_riscv_cv_bitmanip_insert (648, 200, 645);
+  res4 = __builtin_riscv_cv_bitmanip_insert (1648, 1023, 1645); /* { dg-error "invalid argument to built-in function" } */
+  res5 = __builtin_riscv_cv_bitmanip_insert (1648, 1024, 1645);
+  res6 =  __builtin_riscv_cv_bitmanip_insert (1648, 65536, 1645); /* { dg-warning "unsigned conversion from \'int\' to \'short unsigned int\' changes value from \'65536\' to \'0\'" } */
+
+  return res1 + res2 + res3 + res4 + res5 + res6;
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 0eae746e848..537d4a40bb1 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -13111,6 +13111,19 @@ proc check_effective_target_cv_bi { } {
     } "-march=rv32i_xcvbi" ]
 }
 
+# Return 1 if the CORE-V BITMANIP extension is available.
+proc check_effective_target_cv_bitmanip { } {
+    if { !([istarget riscv*-*-*]) } {
+         return 0
+     }
+    return [check_no_compiler_messages cv_bitmanip object {
+        void foo (void)
+        {
+          asm ("cv.extract t0, t1, 20, 20");
+        }
+    } "-march=rv32i_xcvbitmanip" ]
+}
+
 proc check_effective_target_loongarch_sx { } {
     return [check_no_compiler_messages loongarch_lsx assembly {
        #if !defined(__loongarch_sx)
-- 
2.34.1


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

* Re: [PATCH 1/1] RISC-V: Add support for XCVbitmanip extension in CV32E40P
  2023-11-09 10:55 ` [PATCH 1/1] RISC-V: Add support for XCVbitmanip extension in CV32E40P Mary Bennett
@ 2023-12-05 15:30   ` Kito Cheng
  2023-12-06 17:59     ` Jeff Law
  0 siblings, 1 reply; 4+ messages in thread
From: Kito Cheng @ 2023-12-05 15:30 UTC (permalink / raw)
  To: Mary Bennett; +Cc: gcc-patches

> index 7d7b952d817..e7d4ad1760c 100644
> --- a/gcc/config/riscv/corev.md
> +++ b/gcc/config/riscv/corev.md
> @@ -27,6 +27,25 @@
>
>    ;;CORE-V EVENT LOAD
>    UNSPECV_CV_ELW
> +
> +  ;;CORE-V BITMANIP
> +  UNSPEC_CV_BITMANIP_EXTRACT
> +  UNSPEC_CV_BITMANIP_EXTRACT_INSN
> +  UNSPEC_CV_BITMANIP_EXTRACTR_INSN
> +  UNSPEC_CV_BITMANIP_EXTRACTU
> +  UNSPEC_CV_BITMANIP_EXTRACTU_INSN
> +  UNSPEC_CV_BITMANIP_EXTRACTUR_INSN
> +  UNSPEC_CV_BITMANIP_INSERT
> +  UNSPEC_CV_BITMANIP_INSERT_INSN
> +  UNSPEC_CV_BITMANIP_INSERTR_INSN

You could reference bfe, sbfx and ubfx instructions in aarch64.md
to see how to write the insert and extract bit with RTL code.

> +  UNSPEC_CV_BITMANIP_BCLR
> +  UNSPEC_CV_BITMANIP_BCLR_INSN
> +  UNSPEC_CV_BITMANIP_BCLRR_INSN
> +  UNSPEC_CV_BITMANIP_BSET
> +  UNSPEC_CV_BITMANIP_BSET_INSN
> +  UNSPEC_CV_BITMANIP_BSETR_INSN

Just use generic RTL code for bset and bclr is fine, you could
reference bitmanip.md

> +  UNSPEC_CV_BITMANIP_BITREV
> +  UNSPEC_CV_BITMANIP_FL1
>  ])
>

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

* Re: [PATCH 1/1] RISC-V: Add support for XCVbitmanip extension in CV32E40P
  2023-12-05 15:30   ` Kito Cheng
@ 2023-12-06 17:59     ` Jeff Law
  0 siblings, 0 replies; 4+ messages in thread
From: Jeff Law @ 2023-12-06 17:59 UTC (permalink / raw)
  To: Kito Cheng, Mary Bennett; +Cc: gcc-patches



On 12/5/23 08:30, Kito Cheng wrote:
>> index 7d7b952d817..e7d4ad1760c 100644
>> --- a/gcc/config/riscv/corev.md
>> +++ b/gcc/config/riscv/corev.md
>> @@ -27,6 +27,25 @@
>>
>>     ;;CORE-V EVENT LOAD
>>     UNSPECV_CV_ELW
>> +
>> +  ;;CORE-V BITMANIP
>> +  UNSPEC_CV_BITMANIP_EXTRACT
>> +  UNSPEC_CV_BITMANIP_EXTRACT_INSN
>> +  UNSPEC_CV_BITMANIP_EXTRACTR_INSN
>> +  UNSPEC_CV_BITMANIP_EXTRACTU
>> +  UNSPEC_CV_BITMANIP_EXTRACTU_INSN
>> +  UNSPEC_CV_BITMANIP_EXTRACTUR_INSN
>> +  UNSPEC_CV_BITMANIP_INSERT
>> +  UNSPEC_CV_BITMANIP_INSERT_INSN
>> +  UNSPEC_CV_BITMANIP_INSERTR_INSN
> 
> You could reference bfe, sbfx and ubfx instructions in aarch64.md
> to see how to write the insert and extract bit with RTL code.
> 
>> +  UNSPEC_CV_BITMANIP_BCLR
>> +  UNSPEC_CV_BITMANIP_BCLR_INSN
>> +  UNSPEC_CV_BITMANIP_BCLRR_INSN
>> +  UNSPEC_CV_BITMANIP_BSET
>> +  UNSPEC_CV_BITMANIP_BSET_INSN
>> +  UNSPEC_CV_BITMANIP_BSETR_INSN
> 
> Just use generic RTL code for bset and bclr is fine, you could
> reference bitmanip.md
Agreed.  And as a general principle if we can reasonably express the 
semantics of an instruction with RTL, we generally should.  Doing so 
gives the optimizers a chance to improve stuff.

I haven't looked at the patches, but the same might apply to the 
extractions & insertions, though there's more complex in that there's 
multiple implementations and I suspect some general cleanups would 
likely be necessary for that to work.  We started to look at it a bit, 
but concluded there were bigger fish to fry.

jeff

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

end of thread, other threads:[~2023-12-06 18:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-09 10:55 [PATCH 0/1] RISC-V: Support CORE-V XCVBITMAIP extension Mary Bennett
2023-11-09 10:55 ` [PATCH 1/1] RISC-V: Add support for XCVbitmanip extension in CV32E40P Mary Bennett
2023-12-05 15:30   ` Kito Cheng
2023-12-06 17:59     ` 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).