If the target is ZBC or ZBKC, it uses clmul instruction for the CRC
 calculation.         Otherwise, if the target is ZBKB, generates
table-based
 CRC, but for reversing inputs and the output uses bswap and brev8
 instructions.         Add new tests to check CRC generation for ZBC, ZBKC
and
 ZBKB targets.

  gcc/

     * expr.cc (gf2n_poly_long_div_quotient): New function.
     * expr.h (gf2n_poly_long_div_quotient):  New function declaration.
     * hwint.cc (reflect_hwi): New function.
     * hwint.h (reflect_hwi): New function declaration.

  gcc/config/riscv/

     * bitmanip.md (crc_rev<ANYI1:mode><ANYI:mode>4): New expander for
reversed CRC.
     (crc<SUBX1:mode><SUBX:mode>4): New expander for bit-forward CRC.
     * iterators.md (SUBX1, ANYI1): New iterators.
     * riscv-protos.h (generate_reflecting_code_using_brev): New function
declaration.
     (expand_crc_using_clmul): Likewise.
     (expand_reversed_crc_using_clmul): Likewise.
     * riscv.cc (generate_reflecting_code_using_brev): New function.
     (expand_crc_using_clmul): Likewise.
     (expand_reversed_crc_using_clmul): Likewise.
     * riscv.md (UNSPEC_CRC, UNSPEC_CRC_REV):  New unspecs.

  gcc/testsuite/gcc.target/riscv/

        * crc-1-zbc.c: New test.
        * crc-1-zbkc.c: Likewise.
        * crc-10-zbc.c: Likewise.
        * crc-10-zbkc.c: Likewise.
        * crc-12-zbc.c: Likewise.
        * crc-12-zbkc.c: Likewise.
        * crc-13-zbc.c: Likewise.
        * crc-13-zbkc.c: Likewise.
        * crc-14-zbc.c: Likewise.
        * crc-14-zbkc.c: Likewise.
        * crc-17-zbc.c: Likewise.
        * crc-17-zbkc.c: Likewise.
        * crc-18-zbc.c: Likewise.
        * crc-18-zbkc.c: Likewise.
        * crc-21-zbc.c: Likewise.
        * crc-21-zbkc.c: Likewise.
        * crc-22-rv64-zbc.c: Likewise.
        * crc-22-rv64-zbkb.c: Likewise.
        * crc-22-rv64-zbkc.c: Likewise.
        * crc-23-zbc.c: Likewise.
        * crc-23-zbkc.c: Likewise.
        * crc-4-zbc.c: Likewise.
        * crc-4-zbkb.c: Likewise.
        * crc-4-zbkc.c: Likewise.
        * crc-5-zbc.c: Likewise.
        * crc-5-zbkb.c: Likewise.
        * crc-5-zbkc.c: Likewise.
        * crc-6-zbc.c: Likewise.
        * crc-6-zbkc.c: Likewise.
        * crc-7-zbc.c: Likewise.
        * crc-7-zbkc.c: Likewise.
        * crc-8-zbc.c: Likewise.
        * crc-8-zbkb.c: Likewise.
        * crc-8-zbkc.c: Likewise.
        * crc-9-zbc.c: Likewise.
        * crc-9-zbkc.c: Likewise.
        * crc-CCIT-data16-zbc.c: Likewise.
        * crc-CCIT-data16-zbkc.c: Likewise.
        * crc-CCIT-data8-zbc.c: Likewise.
        * crc-CCIT-data8-zbkc.c: Likewise.
        * crc-coremark-16bitdata-zbc.c: Likewise.
        * crc-coremark-16bitdata-zbkc.c: Likewise.

Signed-off-by: Mariam Arutunian <mariamarutun...@gmail.com>
Mentored-by: Jeff Law <j...@ventanamicro.com>
---
 gcc/config/riscv/bitmanip.md                  |  63 +++++++
 gcc/config/riscv/iterators.md                 |   6 +
 gcc/config/riscv/riscv-protos.h               |   3 +
 gcc/config/riscv/riscv.cc                     | 155 ++++++++++++++++++
 gcc/config/riscv/riscv.md                     |   4 +
 gcc/expr.cc                                   |  27 +++
 gcc/expr.h                                    |   5 +
 gcc/hwint.cc                                  |  18 ++
 gcc/hwint.h                                   |   2 +
 gcc/testsuite/gcc.target/riscv/crc-1-zbc.c    |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-1-zbkc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-10-zbc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-10-zbkc.c  |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-12-zbc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-12-zbkc.c  |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-13-zbc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-13-zbkc.c  |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-14-zbc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-14-zbkc.c  |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-17-zbc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-17-zbkc.c  |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-18-zbc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-18-zbkc.c  |  11 ++
 .../gcc.target/riscv/crc-21-rv64-zbc.c        |   9 +
 .../gcc.target/riscv/crc-21-rv64-zbkc.c       |   9 +
 gcc/testsuite/gcc.target/riscv/crc-22-zbc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-22-zbkb.c  |  10 ++
 gcc/testsuite/gcc.target/riscv/crc-22-zbkc.c  |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-23-zbc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-23-zbkc.c  |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-4-zbc.c    |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-4-zbkb.c   |  10 ++
 gcc/testsuite/gcc.target/riscv/crc-4-zbkc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-5-zbc.c    |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-5-zbkb.c   |  10 ++
 gcc/testsuite/gcc.target/riscv/crc-5-zbkc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-6-zbc.c    |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-6-zbkc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-7-zbc.c    |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-7-zbkc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-8-zbc.c    |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-8-zbkb.c   |  10 ++
 gcc/testsuite/gcc.target/riscv/crc-8-zbkc.c   |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-9-zbc.c    |  11 ++
 gcc/testsuite/gcc.target/riscv/crc-9-zbkc.c   |  11 ++
 .../gcc.target/riscv/crc-CCIT-data16-zbc.c    |  11 ++
 .../gcc.target/riscv/crc-CCIT-data16-zbkc.c   |  11 ++
 .../gcc.target/riscv/crc-CCIT-data8-zbc.c     |  11 ++
 .../gcc.target/riscv/crc-CCIT-data8-zbkc.c    |  11 ++
 .../riscv/crc-coremark-16bitdata-zbc.c        |  11 ++
 .../riscv/crc-coremark-16bitdata-zbkc.c       |  11 ++
 51 files changed, 737 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-1-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-1-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-10-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-10-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-12-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-12-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-13-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-13-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-14-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-14-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-17-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-17-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-18-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-18-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-22-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-22-zbkb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-22-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-23-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-23-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-4-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-4-zbkb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-4-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-5-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-5-zbkb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-5-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-6-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-6-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-7-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-7-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-8-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-8-zbkb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-8-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-9-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-9-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbkc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbc.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbkc.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 06ff698bfe7..23dc47eaaef 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -1192,3 +1192,66 @@
   "TARGET_ZBC"
   "clmulr\t%0,%1,%2"
   [(set_attr "type" "clmul")])
+
+;; Reversed CRC 8, 16, 32 for TARGET_64
+(define_expand "crc_rev<ANYI1:mode><ANYI:mode>4"
+	;; return value (calculated CRC)
+  [(set (match_operand:ANYI 0 "register_operand" "=r")
+		      ;; initial CRC
+	(unspec:ANYI [(match_operand:ANYI 1 "register_operand" "r")
+		      ;; data
+		      (match_operand:ANYI1 2 "register_operand" "r")
+		      ;; polynomial without leading 1
+		      (match_operand:ANYI 3)]
+		      UNSPEC_CRC_REV))]
+  /* We don't support the case when data's size is bigger than CRC's size.  */
+  "<ANYI:MODE>mode >= <ANYI1:MODE>mode"
+{
+  /* If we have the ZBC or ZBKC extension (ie, clmul) and
+     it is possible to store the quotient within a single variable
+     (E.g.  CRC64's quotient may need 65 bits,
+     we can't keep it in 64 bit variable.)
+     then use clmul instruction to implement the CRC,
+     otherwise (TARGET_ZBKB) generate table based using brev.  */
+  if ((TARGET_ZBKC || TARGET_ZBC) && <ANYI:MODE>mode < word_mode)
+    expand_reversed_crc_using_clmul (<ANYI:MODE>mode, <ANYI1:MODE>mode,
+				     operands);
+  else if (TARGET_ZBKB)
+    /* Generate table-based CRC.
+       To reflect values use brev and bswap instructions.  */
+    expand_reversed_crc_table_based (operands[0], operands[1],
+				     operands[2], operands[3],
+				     GET_MODE (operands[2]),
+				     generate_reflecting_code_using_brev);
+  else
+    /* Generate table-based CRC.
+       To reflect values use standard reflecting algorithm.  */
+    expand_reversed_crc_table_based (operands[0], operands[1],
+				     operands[2], operands[3],
+				     GET_MODE (operands[2]),
+				     generate_reflecting_code_standard);
+  DONE;
+})
+
+;; CRC 8, 16, (32 for TARGET_64)
+(define_expand "crc<SUBX1:mode><SUBX:mode>4"
+	;; return value (calculated CRC)
+  [(set (match_operand:SUBX 0 "register_operand" "=r")
+		      ;; initial CRC
+	(unspec:SUBX [(match_operand:SUBX 1 "register_operand" "r")
+		      ;; data
+		      (match_operand:SUBX1 2 "register_operand" "r")
+		      ;; polynomial without leading 1
+		      (match_operand:SUBX 3)]
+		      UNSPEC_CRC))]
+  /* We don't support the case when data's size is bigger than CRC's size.  */
+  "(TARGET_ZBKC || TARGET_ZBC) && <SUBX:MODE>mode >= <SUBX1:MODE>mode"
+{
+  /* If we have the ZBC or ZBKC extension (ie, clmul) and
+     it is possible to store the quotient within a single variable
+     (E.g.  CRC64's quotient may need 65 bits,
+     we can't keep it in 64 bit variable.)
+     then use clmul instruction to implement the CRC.  */
+  expand_crc_using_clmul (<SUBX:MODE>mode, <SUBX1:MODE>mode, operands);
+  DONE;
+})
diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index 2844cb02ff0..2204cd61309 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -62,9 +62,15 @@
 ;; Iterator for hardware integer modes narrower than XLEN.
 (define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
 
+;; Iterator for hardware integer modes narrower than XLEN, same as SUBX.
+(define_mode_iterator SUBX1 [QI HI (SI "TARGET_64BIT")])
+
 ;; Iterator for hardware-supported integer modes.
 (define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
 
+;; Iterator for hardware integer modes narrower than XLEN, same as ANYI.
+(define_mode_iterator ANYI1 [QI HI SI (DI "TARGET_64BIT")])
+
 (define_mode_iterator ANYI_DOUBLE_TRUNC [HI SI (DI "TARGET_64BIT")])
 
 (define_mode_iterator ANYI_QUAD_TRUNC [SI (DI "TARGET_64BIT")])
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 3358e3887b9..74ef6af18ce 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -173,6 +173,9 @@ extern bool riscv_reg_frame_related (rtx);
 extern void riscv_split_sum_of_two_s12 (HOST_WIDE_INT, HOST_WIDE_INT *,
 					HOST_WIDE_INT *);
 extern bool riscv_vector_float_type_p (const_tree type);
+extern void generate_reflecting_code_using_brev (rtx *, int);
+extern void expand_crc_using_clmul (scalar_mode, scalar_mode, rtx *);
+extern void expand_reversed_crc_using_clmul (scalar_mode, scalar_mode, rtx *);
 
 /* Routines implemented in riscv-c.cc.  */
 void riscv_cpu_cpp_builtins (cpp_reader *);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 6efe14ff199..d2cb29b6201 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -12392,6 +12392,161 @@ riscv_stack_clash_protection_alloca_probe_range (void)
   return STACK_CLASH_CALLER_GUARD;
 }
 
+/* Generate instruction sequence
+   which reflects the value of the OP using bswap and brev8 instructions.
+   OP's mode may be less than word_mode, to get the correct number,
+   after reflecting we shift right the value by SHIFT_VAL.
+   E.g. we have 1111 0001, after reflection (target 32-bit) we will get
+   1000 1111 0000 0000, if we shift-out 16 bits,
+   we will get the desired one: 1000 1111.  */
+
+void
+generate_reflecting_code_using_brev (rtx *op, int shift_val)
+{
+
+  riscv_expand_op (BSWAP, word_mode, *op, *op, *op);
+  riscv_expand_op (LSHIFTRT, word_mode, *op, *op,
+		   gen_int_mode (shift_val, word_mode));
+  if (TARGET_64BIT)
+    emit_insn (gen_riscv_brev8_di (*op, *op));
+  else
+    emit_insn (gen_riscv_brev8_si (*op, *op));
+}
+
+
+/* Generate assembly to calculate CRC using clmul instruction.
+   The following code will be generated when the CRC and data sizes are equal:
+     li      a4,quotient
+     li      a5,polynomial
+     xor     a0,a1,a0
+     clmul   a0,a0,a4
+     srli    a0,a0,crc_size
+     clmul   a0,a0,a5
+     slli    a0,a0,word_mode_size - crc_size
+     srli    a0,a0,word_mode_size - crc_size
+     ret
+   crc_size may be 8, 16, 32.
+   Some instructions will be added for the cases when CRC's size is larger than
+   data's size.
+   OPERANDS[1] is input CRC,
+   OPERANDS[2] is data (message),
+   OPERANDS[3] is the polynomial without the leading 1.  */
+
+void
+expand_crc_using_clmul (scalar_mode crc_mode, scalar_mode data_mode,
+			rtx *operands)
+{
+  /* Check and keep arguments.  */
+  gcc_assert (!CONST_INT_P (operands[0]));
+  gcc_assert (CONST_INT_P (operands[3]));
+  unsigned short crc_size = GET_MODE_BITSIZE (crc_mode);
+  gcc_assert (crc_size <= 32);
+  unsigned short data_size = GET_MODE_BITSIZE (data_mode);
+
+  /* Calculate the quotient.  */
+  unsigned HOST_WIDE_INT
+      q = gf2n_poly_long_div_quotient (UINTVAL (operands[3]), crc_size);
+
+  rtx crc_extended = gen_rtx_ZERO_EXTEND (word_mode, operands[1]);
+  rtx crc = gen_reg_rtx (word_mode);
+  if (crc_size > data_size)
+    riscv_expand_op (LSHIFTRT, word_mode, crc, crc_extended,
+		     gen_int_mode (crc_size - data_size, word_mode));
+  else
+    crc = gen_rtx_ZERO_EXTEND (word_mode, operands[1]);
+  rtx t0 = gen_reg_rtx (word_mode);
+  riscv_emit_move (t0, gen_int_mode (q, word_mode));
+  rtx t1 = gen_reg_rtx (word_mode);
+  riscv_emit_move (t1, operands[3]);
+
+  rtx a0 = gen_reg_rtx (word_mode);
+  rtx data = gen_rtx_ZERO_EXTEND (word_mode, operands[2]);
+  riscv_expand_op (XOR, word_mode, a0, crc, data);
+
+  if (TARGET_64BIT)
+    emit_insn (gen_riscv_clmul_di (a0, a0, t0));
+  else
+    emit_insn (gen_riscv_clmul_si (a0, a0, t0));
+
+  riscv_expand_op (LSHIFTRT, word_mode, a0, a0,
+		   gen_int_mode (crc_size, word_mode));
+  if (TARGET_64BIT)
+    emit_insn (gen_riscv_clmul_di (a0, a0, t1));
+  else
+    emit_insn (gen_riscv_clmul_si (a0, a0, t1));
+
+  if (crc_size > data_size)
+    {
+      rtx crc_part = gen_reg_rtx (word_mode);
+      riscv_expand_op (ASHIFT, word_mode, crc_part, operands[1],
+		       gen_int_mode (data_size, word_mode));
+      riscv_expand_op (XOR, word_mode, a0, a0, crc_part);
+    }
+  riscv_emit_move (operands[0], gen_lowpart (crc_mode, a0));
+}
+
+/* Generate assembly to calculate reversed CRC using clmul instruction.
+   OPERANDS[1] is input CRC,
+   OPERANDS[2] is data (message),
+   OPERANDS[3] is the polynomial without the leading 1.  */
+
+void
+expand_reversed_crc_using_clmul (scalar_mode crc_mode, scalar_mode data_mode,
+				 rtx *operands)
+{
+  /* Check and keep arguments.  */
+  gcc_assert (!CONST_INT_P (operands[0]));
+  gcc_assert (CONST_INT_P (operands[3]));
+  unsigned short crc_size = GET_MODE_BITSIZE (crc_mode);
+  gcc_assert (crc_size <= 32);
+  unsigned short data_size = GET_MODE_BITSIZE (data_mode);
+  rtx polynomial = operands[3];
+
+  /* Calculate the quotient.  */
+  unsigned HOST_WIDE_INT
+  q = gf2n_poly_long_div_quotient (UINTVAL (polynomial), crc_size);
+  /* Reflect the calculated quotient.  */
+  q = reflect_hwi (q, crc_size + 1);
+  rtx t0 = gen_reg_rtx (word_mode);
+  riscv_emit_move (t0, gen_int_mode (q, word_mode));
+
+  /* Reflect the polynomial.  */
+  unsigned HOST_WIDE_INT
+  ref_polynomial = reflect_hwi (UINTVAL (polynomial),
+				crc_size);
+  rtx t1 = gen_reg_rtx (word_mode);
+  riscv_emit_move (t1, gen_int_mode (ref_polynomial << 1, word_mode));
+
+  rtx crc = gen_rtx_ZERO_EXTEND (word_mode, operands[1]);
+  rtx data = gen_rtx_ZERO_EXTEND (word_mode, operands[2]);
+  rtx a0 = gen_reg_rtx (word_mode);
+  riscv_expand_op (XOR, word_mode, a0, crc, data);
+
+  if (TARGET_64BIT)
+    emit_insn (gen_riscv_clmul_di (a0, a0, t0));
+  else
+    emit_insn (gen_riscv_clmul_si (a0, a0, t0));
+
+  rtx num_shift = gen_int_mode (GET_MODE_BITSIZE (word_mode) - data_size,
+				word_mode);
+  riscv_expand_op (ASHIFT, word_mode, a0, a0, num_shift);
+
+  if (TARGET_64BIT)
+    emit_insn (gen_riscv_clmulh_di (a0, a0, t1));
+  else
+    emit_insn (gen_riscv_clmulh_si (a0, a0, t1));
+
+  if (crc_size > data_size)
+    {
+      rtx data_size_shift = gen_int_mode (data_size, word_mode);
+      rtx crc_part = gen_reg_rtx (word_mode);
+      riscv_expand_op (LSHIFTRT, word_mode, crc_part, crc, data_size_shift);
+      riscv_expand_op (XOR, word_mode, a0, a0, crc_part);
+    }
+
+  riscv_emit_move (operands[0], gen_lowpart (crc_mode, a0));
+}
+
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 9f94b5aa023..ca8e165540e 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -93,6 +93,10 @@
   ;; XTheadFmv moves
   UNSPEC_XTHEADFMV
   UNSPEC_XTHEADFMV_HW
+
+  ;; CRC unspecs
+  UNSPEC_CRC
+  UNSPEC_CRC_REV
 ])
 
 (define_c_enum "unspecv" [
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 3a0ddfaf132..d2aa7afb608 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -14125,6 +14125,33 @@ int_expr_size (const_tree exp)
   return tree_to_shwi (size);
 }
 
+/* Return the quotient of polynomial long division of x^2N by POLYNOMIAL
+   in GF (2^N).
+   Author: Richard Sandiford <richard.sandiford@arm.com>  */
+
+unsigned HOST_WIDE_INT
+gf2n_poly_long_div_quotient (unsigned HOST_WIDE_INT polynomial,
+			     unsigned short n)
+{
+  /* The result has degree N, so needs N + 1 bits.  */
+  gcc_assert (n < 64);
+
+  /* Perform a division step for the x^2N coefficient.  At this point the
+     quotient and remainder have N implicit trailing zeros.  */
+  unsigned HOST_WIDE_INT quotient = 1;
+  unsigned HOST_WIDE_INT remainder = polynomial;
+
+  /* Process the coefficients for x^(2N-1) down to x^N, with each step
+     reducing the number of implicit trailing zeros by one.  */
+  for (unsigned int i = 0; i < n; ++i)
+    {
+      bool coeff = remainder & (HOST_WIDE_INT_1U << (n - 1));
+      quotient = (quotient << 1) | coeff;
+      remainder = (remainder << 1) ^ (coeff ? polynomial : 0);
+    }
+  return quotient;
+}
+
 /* Calculate CRC for the initial CRC and given POLYNOMIAL.
    CRC_BITS is CRC size.  */
 
diff --git a/gcc/expr.h b/gcc/expr.h
index 9373c7913a2..e15300eebba 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -377,6 +377,11 @@ extern rtx expr_size (tree);
 extern bool mem_ref_refers_to_non_mem_p (tree);
 extern bool non_mem_decl_p (tree);
 
+/* Return the quotient of the polynomial long division of x^2N by POLYNOMIAL
+   in GF (2^N).  */
+extern unsigned HOST_WIDE_INT
+gf2n_poly_long_div_quotient (unsigned HOST_WIDE_INT, unsigned short);
+
 /* Generate table-based CRC.  */
 extern void generate_reflecting_code_standard (rtx *, int);
 extern void expand_crc_table_based (rtx, rtx, rtx, rtx, machine_mode);
diff --git a/gcc/hwint.cc b/gcc/hwint.cc
index e5c3619a35b..7c3b2d21515 100644
--- a/gcc/hwint.cc
+++ b/gcc/hwint.cc
@@ -188,3 +188,21 @@ least_common_multiple (HOST_WIDE_INT a, HOST_WIDE_INT b)
 {
   return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
 }
+
+/* Reflect (reverse) the bits of a given VALUE within a specified BITWIDTH.  */
+
+unsigned HOST_WIDE_INT
+reflect_hwi (unsigned HOST_WIDE_INT value, unsigned bitwidth)
+{
+  unsigned HOST_WIDE_INT reflectedValue = 0;
+  /* Loop through each bit in the specified BITWIDTH.  */
+  for (size_t i = 0; i < bitwidth; i++)
+    {
+      reflectedValue <<= 1;
+      /* Add the least significant bit of the current value to the
+	 reflected value.  */
+      reflectedValue |= (value & 1);
+      value >>= 1;
+    }
+  return reflectedValue;
+}
\ No newline at end of file
diff --git a/gcc/hwint.h b/gcc/hwint.h
index 25a94bedef1..60a9c2e1f28 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -284,6 +284,7 @@ extern HOST_WIDE_INT gcd (HOST_WIDE_INT, HOST_WIDE_INT);
 extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
 extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
 extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT);
+extern unsigned HOST_WIDE_INT reflect_hwi (unsigned HOST_WIDE_INT, unsigned);
 
 /* Like ctz_hwi, except 0 when x == 0.  */
 
@@ -396,4 +397,5 @@ mul_hwi (HOST_WIDE_INT a, HOST_WIDE_INT b, bool *overflow)
 #endif
 }
 
+
 #endif /* ! GCC_HWINT_H */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-1-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-1-zbc.c
new file mode 100644
index 00000000000..c16224d045a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-1-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish  -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-1.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-1-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-1-zbkc.c
new file mode 100644
index 00000000000..8c627c0431a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-1-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish  -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-1.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-10-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-10-zbc.c
new file mode 100644
index 00000000000..7a69ae673e6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-10-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-10.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-10-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-10-zbkc.c
new file mode 100644
index 00000000000..c4e65f8f758
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-10-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-10.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-12-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-12-zbc.c
new file mode 100644
index 00000000000..919796e4818
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-12-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish  -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-12.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-12-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-12-zbkc.c
new file mode 100644
index 00000000000..674edb39de2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-12-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish  -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-12.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-13-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-13-zbc.c
new file mode 100644
index 00000000000..a6f131c1c49
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-13-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-13.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-13-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-13-zbkc.c
new file mode 100644
index 00000000000..c59c6ee5959
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-13-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-13.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-14-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-14-zbc.c
new file mode 100644
index 00000000000..a4a1c948194
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-14-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-14.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-14-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-14-zbkc.c
new file mode 100644
index 00000000000..a7c1381eebe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-14-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-14.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-17-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-17-zbc.c
new file mode 100644
index 00000000000..244c22a6e86
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-17-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-17.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-17-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-17-zbkc.c
new file mode 100644
index 00000000000..879fc285330
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-17-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-17.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-18-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-18-zbc.c
new file mode 100644
index 00000000000..b4e6aa3b063
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-18-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-18.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-18-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-18-zbkc.c
new file mode 100644
index 00000000000..6b4d2531678
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-18-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-18.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbc.c
new file mode 100644
index 00000000000..261fe701933
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbc.c
@@ -0,0 +1,9 @@
+/* { dg-do run { target { riscv64*-*-* } } } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish  -march=rv64gc_zbc" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-21.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbkc.c
new file mode 100644
index 00000000000..0b5142640c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-21-rv64-zbkc.c
@@ -0,0 +1,9 @@
+/* { dg-do run { target { riscv64*-*-* } } } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish  -march=rv64gc_zbkc" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-21.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-22-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-22-zbc.c
new file mode 100644
index 00000000000..e7249b5132f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-22-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-22.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-22-zbkb.c b/gcc/testsuite/gcc.target/riscv/crc-22-zbkb.c
new file mode 100644
index 00000000000..f63ef4e8d9f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-22-zbkb.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc-details" } */
+/* { dg-additional-options "-march=rv64gc_zbkb" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkb" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#include "../../gcc.dg/torture/crc-22.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-22-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-22-zbkc.c
new file mode 100644
index 00000000000..7499d151557
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-22-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-22.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-23-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-23-zbc.c
new file mode 100644
index 00000000000..2c2b91f8e3b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-23-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-23.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-23-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-23-zbkc.c
new file mode 100644
index 00000000000..59439ee6706
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-23-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-23.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-4-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-4-zbc.c
new file mode 100644
index 00000000000..c7c859a16e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-4-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-4.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-4-zbkb.c b/gcc/testsuite/gcc.target/riscv/crc-4-zbkb.c
new file mode 100644
index 00000000000..7017de9bec9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-4-zbkb.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc-details" } */
+/* { dg-additional-options "-march=rv64gc_zbkb" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkb" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#include "../../gcc.dg/torture/crc-4.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-4-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-4-zbkc.c
new file mode 100644
index 00000000000..3601af1ab81
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-4-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-4.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-5-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-5-zbc.c
new file mode 100644
index 00000000000..54f8c6b2172
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-5-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-5.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-5-zbkb.c b/gcc/testsuite/gcc.target/riscv/crc-5-zbkb.c
new file mode 100644
index 00000000000..ee327064dce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-5-zbkb.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc-details" } */
+/* { dg-additional-options "-march=rv64gc_zbkb" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkb" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#include "../../gcc.dg/torture/crc-5.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-5-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-5-zbkc.c
new file mode 100644
index 00000000000..956bdd417db
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-5-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-5.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-6-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-6-zbc.c
new file mode 100644
index 00000000000..49e79397e4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-6-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-6.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-6-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-6-zbkc.c
new file mode 100644
index 00000000000..e5316f4cfb3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-6-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-6.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-7-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-7-zbc.c
new file mode 100644
index 00000000000..2be80ee467e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-7-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-7.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-7-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-7-zbkc.c
new file mode 100644
index 00000000000..5b9db3c5372
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-7-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-7.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-8-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-8-zbc.c
new file mode 100644
index 00000000000..be3564050f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-8-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-8.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-8-zbkb.c b/gcc/testsuite/gcc.target/riscv/crc-8-zbkb.c
new file mode 100644
index 00000000000..f9bd4945fbf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-8-zbkb.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc-details" } */
+/* { dg-additional-options "-march=rv64gc_zbkb" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkb" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Os" "-Oz" "-Og" "-flto"} } */
+
+#include "../../gcc.dg/torture/crc-8.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-8-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-8-zbkc.c
new file mode 100644
index 00000000000..e7a3520a3b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-8-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-8.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-9-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-9-zbc.c
new file mode 100644
index 00000000000..9b05264d149
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-9-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-9.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-9-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-9-zbkc.c
new file mode 100644
index 00000000000..30df5e695cf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-9-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-9.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
diff --git a/gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbc.c
new file mode 100644
index 00000000000..b21d7f07e0b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-CCIT-data16.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbkc.c
new file mode 100644
index 00000000000..5f66a9d405f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data16-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-CCIT-data16.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbc.c
new file mode 100644
index 00000000000..0a7b83b35c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-CCIT-data8.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbkc.c
new file mode 100644
index 00000000000..c68ee27c123
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-CCIT-data8-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-CCIT-data8.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbc.c b/gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbc.c
new file mode 100644
index 00000000000..20d1ad42813
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-coremark16-data16.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbkc.c b/gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbkc.c
new file mode 100644
index 00000000000..4da3e8b2543
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/crc-coremark-16bitdata-zbkc.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-w -fdump-tree-crc -fdump-rtl-dfinish " } */
+/* { dg-additional-options "-march=rv64gc_zbkc" { target { rv64 } } } */
+/* { dg-additional-options "-march=rv32gc_zbkc" { target { rv32 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+#include "../../gcc.dg/torture/crc-coremark16-data16.c"
+
+/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */
+/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */
+/* { dg-final { scan-rtl-dump "clmul" "dfinish"} } */
\ No newline at end of file
-- 
2.25.1

Reply via email to