[v3,2/3] RISC-V: Add support for XCVbi extension in CV32E40P

Message ID 20240108132432.901738-3-mary.bennett@embecosm.com
State New
Headers
Series RISC-V: Support CORE-V XCVELW, XCVBI, and XCVMEM extensions |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Testing passed

Commit Message

Mary Bennett Jan. 8, 2024, 1:24 p.m. UTC
  Spec: https://docs.openhwgroup.org/projects/cv32e40p-user-manual/en/latest/instruction_set_extensions.html

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>
  Nazareno Bruschi <nazareno.bruschi@embecosm.com>
  Lin Sinan

include/ChangeLog:
	* opcode/riscv-opc.h: Add corresponding MATCH and MASK
	  macros for XCVbi.
	* opcode/riscv.h: Add corresponding EXTRACT and ENCODE macros
          for XCVbi.
	(enum riscv_insn_class): Add the XCVbi instruction class.

gas/ChangeLog:
	* config/tc-riscv.c (validate_riscv_insn): Add the necessary
	  operands for the extension.
	(riscv_ip): Likewise.
	* doc/c-riscv.texi: Note XCVbi as an additional ISA extension
	  for CORE-V.
	* testsuite/gas/riscv/cv-bi-beqimm.d: New test.
	* testsuite/gas/riscv/cv-bi-beqimm.s: New test.
	* testsuite/gas/riscv/cv-bi-bneimm.d: New test.
	* testsuite/gas/riscv/cv-bi-bneimm.s: New test.
	* testsuite/gas/riscv/cv-bi-fail-march.d: New test.
	* testsuite/gas/riscv/cv-bi-fail-march.l: New test.
	* testsuite/gas/riscv/cv-bi-fail-march.s: New test.
	* testsuite/gas/riscv/cv-bi-fail-operand-01.d: New test.
	* testsuite/gas/riscv/cv-bi-fail-operand-01.l: New test.
	* testsuite/gas/riscv/cv-bi-fail-operand-01.s: New test.
	* testsuite/gas/riscv/cv-bi-fail-operand-02.d: New test.
	* testsuite/gas/riscv/cv-bi-fail-operand-02.l: New test.
	* testsuite/gas/riscv/cv-bi-fail-operand-02.s: New test.
	* testsuite/gas/riscv/cv-bi-fail-operand-03.d: New test.
	* testsuite/gas/riscv/cv-bi-fail-operand-03.l: New test.
	* testsuite/gas/riscv/cv-bi-fail-operand-03.s: New test.

include/ChangeLog:
        * opcode/riscv-opc.h: Add corresponding MATCH and MASK
          macros for XCVbi.
        * opcode/riscv.h: Add corresponding EXTRACT and ENCODE macros
          for XCVbi.
        (enum riscv_insn_class): Add the XCVbi instruction class.

ld/ChangeLog:
	* testsuite/ld-riscv-elf/cv-bi-beqimm.d: New test.
	* testsuite/ld-riscv-elf/cv-bi-beqimm.s: New test.
	* testsuite/ld-riscv-elf/cv-bi-bneimm.d: New test.
	* testsuite/ld-riscv-elf/cv-bi-bneimm.s: New test.
	* testsuite/ld-riscv-elf/ld-riscv-elf.exp: Add new tests.

opcodes/ChangeLog:
	* riscv-dis.c (print_insn_args): Add disassembly for new operand.
	* riscv-opc.c: Add XCVbi instructions.
---
 bfd/elfxx-riscv.c                             |  5 +++++
 gas/config/tc-riscv.c                         | 12 ++++++++++-
 gas/doc/c-riscv.texi                          |  5 +++++
 gas/testsuite/gas/riscv/cv-bi-beqimm.d        | 12 +++++++++++
 gas/testsuite/gas/riscv/cv-bi-beqimm.s        |  4 ++++
 gas/testsuite/gas/riscv/cv-bi-bneimm.d        | 12 +++++++++++
 gas/testsuite/gas/riscv/cv-bi-bneimm.s        |  4 ++++
 gas/testsuite/gas/riscv/cv-bi-fail-march.d    |  3 +++
 gas/testsuite/gas/riscv/cv-bi-fail-march.l    |  3 +++
 gas/testsuite/gas/riscv/cv-bi-fail-march.s    |  5 +++++
 .../gas/riscv/cv-bi-fail-operand-01.d         |  3 +++
 .../gas/riscv/cv-bi-fail-operand-01.l         |  3 +++
 .../gas/riscv/cv-bi-fail-operand-01.s         |  4 ++++
 .../gas/riscv/cv-bi-fail-operand-02.d         |  3 +++
 .../gas/riscv/cv-bi-fail-operand-02.l         |  3 +++
 .../gas/riscv/cv-bi-fail-operand-02.s         |  4 ++++
 .../gas/riscv/cv-bi-fail-operand-03.d         |  3 +++
 .../gas/riscv/cv-bi-fail-operand-03.l         |  9 ++++++++
 .../gas/riscv/cv-bi-fail-operand-03.s         | 10 +++++++++
 include/opcode/riscv-opc.h                    |  5 +++++
 include/opcode/riscv.h                        |  4 ++++
 ld/testsuite/ld-riscv-elf/cv-bi-beqimm.d      | 21 +++++++++++++++++++
 ld/testsuite/ld-riscv-elf/cv-bi-beqimm.s      | 11 ++++++++++
 ld/testsuite/ld-riscv-elf/cv-bi-bneimm.d      | 21 +++++++++++++++++++
 ld/testsuite/ld-riscv-elf/cv-bi-bneimm.s      | 11 ++++++++++
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp    |  2 ++
 opcodes/riscv-dis.c                           |  4 ++++
 opcodes/riscv-opc.c                           |  4 ++++
 28 files changed, 189 insertions(+), 1 deletion(-)
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-beqimm.d
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-beqimm.s
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-bneimm.d
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-bneimm.s
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-march.d
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-march.l
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-march.s
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-01.d
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-01.l
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-01.s
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-02.d
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-02.l
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-02.s
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-03.d
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-03.l
 create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-03.s
 create mode 100644 ld/testsuite/ld-riscv-elf/cv-bi-beqimm.d
 create mode 100644 ld/testsuite/ld-riscv-elf/cv-bi-beqimm.s
 create mode 100644 ld/testsuite/ld-riscv-elf/cv-bi-bneimm.d
 create mode 100644 ld/testsuite/ld-riscv-elf/cv-bi-bneimm.s
  

Comments

Nelson Chu Jan. 12, 2024, 12:46 a.m. UTC | #1
On Mon, Jan 8, 2024 at 9:41 PM Mary Bennett <mary.bennett@embecosm.com>
wrote:

> Spec:
> https://docs.openhwgroup.org/projects/cv32e40p-user-manual/en/latest/instruction_set_extensions.html
>
> 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>
>   Nazareno Bruschi <nazareno.bruschi@embecosm.com>
>   Lin Sinan
>
> include/ChangeLog:
>         * opcode/riscv-opc.h: Add corresponding MATCH and MASK
>           macros for XCVbi.
>         * opcode/riscv.h: Add corresponding EXTRACT and ENCODE macros
>           for XCVbi.
>         (enum riscv_insn_class): Add the XCVbi instruction class.
>
> gas/ChangeLog:
>         * config/tc-riscv.c (validate_riscv_insn): Add the necessary
>           operands for the extension.
>         (riscv_ip): Likewise.
>         * doc/c-riscv.texi: Note XCVbi as an additional ISA extension
>           for CORE-V.
>         * testsuite/gas/riscv/cv-bi-beqimm.d: New test.
>         * testsuite/gas/riscv/cv-bi-beqimm.s: New test.
>         * testsuite/gas/riscv/cv-bi-bneimm.d: New test.
>         * testsuite/gas/riscv/cv-bi-bneimm.s: New test.
>         * testsuite/gas/riscv/cv-bi-fail-march.d: New test.
>         * testsuite/gas/riscv/cv-bi-fail-march.l: New test.
>         * testsuite/gas/riscv/cv-bi-fail-march.s: New test.
>         * testsuite/gas/riscv/cv-bi-fail-operand-01.d: New test.
>         * testsuite/gas/riscv/cv-bi-fail-operand-01.l: New test.
>         * testsuite/gas/riscv/cv-bi-fail-operand-01.s: New test.
>         * testsuite/gas/riscv/cv-bi-fail-operand-02.d: New test.
>         * testsuite/gas/riscv/cv-bi-fail-operand-02.l: New test.
>         * testsuite/gas/riscv/cv-bi-fail-operand-02.s: New test.
>         * testsuite/gas/riscv/cv-bi-fail-operand-03.d: New test.
>         * testsuite/gas/riscv/cv-bi-fail-operand-03.l: New test.
>         * testsuite/gas/riscv/cv-bi-fail-operand-03.s: New test.
>
> include/ChangeLog:
>         * opcode/riscv-opc.h: Add corresponding MATCH and MASK
>           macros for XCVbi.
>         * opcode/riscv.h: Add corresponding EXTRACT and ENCODE macros
>           for XCVbi.
>         (enum riscv_insn_class): Add the XCVbi instruction class.
>
> ld/ChangeLog:
>         * testsuite/ld-riscv-elf/cv-bi-beqimm.d: New test.
>         * testsuite/ld-riscv-elf/cv-bi-beqimm.s: New test.
>         * testsuite/ld-riscv-elf/cv-bi-bneimm.d: New test.
>         * testsuite/ld-riscv-elf/cv-bi-bneimm.s: New test.
>         * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Add new tests.
>

Seems like this patch doesn't change ld code, so not sure if the ld test
cases are needed or not?

Nelson

opcodes/ChangeLog:
>         * riscv-dis.c (print_insn_args): Add disassembly for new operand.
>         * riscv-opc.c: Add XCVbi instructions.
> ---
>  bfd/elfxx-riscv.c                             |  5 +++++
>  gas/config/tc-riscv.c                         | 12 ++++++++++-
>  gas/doc/c-riscv.texi                          |  5 +++++
>  gas/testsuite/gas/riscv/cv-bi-beqimm.d        | 12 +++++++++++
>  gas/testsuite/gas/riscv/cv-bi-beqimm.s        |  4 ++++
>  gas/testsuite/gas/riscv/cv-bi-bneimm.d        | 12 +++++++++++
>  gas/testsuite/gas/riscv/cv-bi-bneimm.s        |  4 ++++
>  gas/testsuite/gas/riscv/cv-bi-fail-march.d    |  3 +++
>  gas/testsuite/gas/riscv/cv-bi-fail-march.l    |  3 +++
>  gas/testsuite/gas/riscv/cv-bi-fail-march.s    |  5 +++++
>  .../gas/riscv/cv-bi-fail-operand-01.d         |  3 +++
>  .../gas/riscv/cv-bi-fail-operand-01.l         |  3 +++
>  .../gas/riscv/cv-bi-fail-operand-01.s         |  4 ++++
>  .../gas/riscv/cv-bi-fail-operand-02.d         |  3 +++
>  .../gas/riscv/cv-bi-fail-operand-02.l         |  3 +++
>  .../gas/riscv/cv-bi-fail-operand-02.s         |  4 ++++
>  .../gas/riscv/cv-bi-fail-operand-03.d         |  3 +++
>  .../gas/riscv/cv-bi-fail-operand-03.l         |  9 ++++++++
>  .../gas/riscv/cv-bi-fail-operand-03.s         | 10 +++++++++
>  include/opcode/riscv-opc.h                    |  5 +++++
>  include/opcode/riscv.h                        |  4 ++++
>  ld/testsuite/ld-riscv-elf/cv-bi-beqimm.d      | 21 +++++++++++++++++++
>  ld/testsuite/ld-riscv-elf/cv-bi-beqimm.s      | 11 ++++++++++
>  ld/testsuite/ld-riscv-elf/cv-bi-bneimm.d      | 21 +++++++++++++++++++
>  ld/testsuite/ld-riscv-elf/cv-bi-bneimm.s      | 11 ++++++++++
>  ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp    |  2 ++
>  opcodes/riscv-dis.c                           |  4 ++++
>  opcodes/riscv-opc.c                           |  4 ++++
>  28 files changed, 189 insertions(+), 1 deletion(-)
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-beqimm.d
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-beqimm.s
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-bneimm.d
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-bneimm.s
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-march.d
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-march.l
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-march.s
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-01.d
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-01.l
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-01.s
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-02.d
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-02.l
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-02.s
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-03.d
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-03.l
>  create mode 100644 gas/testsuite/gas/riscv/cv-bi-fail-operand-03.s
>  create mode 100644 ld/testsuite/ld-riscv-elf/cv-bi-beqimm.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/cv-bi-beqimm.s
>  create mode 100644 ld/testsuite/ld-riscv-elf/cv-bi-bneimm.d
>  create mode 100644 ld/testsuite/ld-riscv-elf/cv-bi-bneimm.s
>
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index b8e64a17da0..646f1eddb70 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1370,6 +1370,7 @@ static struct riscv_supported_ext
> riscv_supported_vendor_x_ext[] =
>    {"xcvmac",           ISA_SPEC_CLASS_DRAFT,   1, 0, 0 },
>    {"xcvalu",           ISA_SPEC_CLASS_DRAFT,   1, 0, 0 },
>    {"xcvelw",           ISA_SPEC_CLASS_DRAFT,   1, 0, 0 },
> +  {"xcvbi",            ISA_SPEC_CLASS_DRAFT,   1, 0, 0 },
>    {"xtheadba",         ISA_SPEC_CLASS_DRAFT,   1, 0, 0 },
>    {"xtheadbb",         ISA_SPEC_CLASS_DRAFT,   1, 0, 0 },
>    {"xtheadbs",         ISA_SPEC_CLASS_DRAFT,   1, 0, 0 },
> @@ -2579,6 +2580,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t
> *rps,
>        return riscv_subset_supports (rps, "xcvalu");
>      case INSN_CLASS_XCVELW:
>        return riscv_subset_supports (rps, "xcvelw");
> +    case INSN_CLASS_XCVBI:
> +      return riscv_subset_supports (rps, "xcvbi");
>      case INSN_CLASS_XTHEADBA:
>        return riscv_subset_supports (rps, "xtheadba");
>      case INSN_CLASS_XTHEADBB:
> @@ -2833,6 +2836,8 @@ riscv_multi_subset_supports_ext
> (riscv_parse_subset_t *rps,
>        return "xcvalu";
>      case INSN_CLASS_XCVELW:
>        return "xcvelw";
> +    case INSN_CLASS_XCVBI:
> +      return "xcvbi";
>      case INSN_CLASS_XTHEADBA:
>        return "xtheadba";
>      case INSN_CLASS_XTHEADBB:
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index a4161420128..77c42e5d8f4 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -1501,7 +1501,7 @@ validate_riscv_insn (const struct riscv_opcode *opc,
> int length)
>               switch (*++oparg)
>                 {
>                   case '2':
> -                   /* ls2[4:0] */
> +                 case '4':
>                     used_bits |= ENCODE_CV_IS2_UIMM5 (-1U);
>                     break;
>                   case '3':
> @@ -3770,6 +3770,16 @@ riscv_ip (char *str, struct riscv_cl_insn *ip,
> expressionS *imm_expr,
>                         ip->insn_opcode
>                             |= ENCODE_CV_IS3_UIMM5
> (imm_expr->X_add_number);
>                         continue;
> +                     case '4':
> +                       my_getExpression (imm_expr, asarg);
> +                       check_absolute_expr (ip, imm_expr, FALSE);
> +                       asarg = expr_parse_end;
> +                       if (imm_expr->X_add_number < -16
> +                           || imm_expr->X_add_number > 15)
> +                         break;
> +                       ip->insn_opcode
> +                           |= ENCODE_CV_IS2_UIMM5
> (imm_expr->X_add_number);
> +                       continue;
>                       default:
>                         goto unknown_riscv_ip_operand;
>                     }
> diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
> index d1712b578a0..d983f9b7bba 100644
> --- a/gas/doc/c-riscv.texi
> +++ b/gas/doc/c-riscv.texi
> @@ -755,6 +755,11 @@ The Xcvelw extension provides instructions for event
> load word operations.
>
>  It is documented in @url{
> https://docs.openhwgroup.org/projects/cv32e40p-user-manual/en/latest/instruction_set_extensions.html
> }
>
> +@item Xcvbi
> +The Xcvbi extension provides instructions for branch immediate operations.
> +
> +It is documented in @url{
> https://docs.openhwgroup.org/projects/cv32e40p-user-manual/en/latest/instruction_set_extensions.html
> }
> +
>  @item XTheadBa
>  The XTheadBa extension provides instructions for address calculations.
>
> diff --git a/gas/testsuite/gas/riscv/cv-bi-beqimm.d
> b/gas/testsuite/gas/riscv/cv-bi-beqimm.d
> new file mode 100644
> index 00000000000..97ef57d91cc
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-beqimm.d
> @@ -0,0 +1,12 @@
> +#as: -march=rv32i_xcvbi
> +#objdump: -d
> +
> +.*:[   ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <foo>:
> +[      ]+0:[   ]+0102e00b[     ]+cv.beqimm[    ]+t0,-16,0 +<foo>
> +[      ]+4:[   ]+fe5eee8b[     ]+cv.beqimm[    ]+t4,5,0 +<foo>
> +[      ]+8:[   ]+fef3ec8b[     ]+cv.beqimm[    ]+t2,15,0 +<foo>
> diff --git a/gas/testsuite/gas/riscv/cv-bi-beqimm.s
> b/gas/testsuite/gas/riscv/cv-bi-beqimm.s
> new file mode 100644
> index 00000000000..7fbb8f27515
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-beqimm.s
> @@ -0,0 +1,4 @@
> +foo:
> +       cv.beqimm t0, -16, foo
> +       cv.beqimm t4, 5, foo
> +       cv.beqimm t2, 15, foo
> diff --git a/gas/testsuite/gas/riscv/cv-bi-bneimm.d
> b/gas/testsuite/gas/riscv/cv-bi-bneimm.d
> new file mode 100644
> index 00000000000..7dddf408107
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-bneimm.d
> @@ -0,0 +1,12 @@
> +#as: -march=rv32i_xcvbi
> +#objdump: -d
> +
> +.*:[   ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <foo>:
> +[      ]+0:[   ]+0102f00b[     ]+cv.bneimm[    ]+t0,-16,0 +<foo>
> +[      ]+4:[   ]+fe5efe8b[     ]+cv.bneimm[    ]+t4,5,0 +<foo>
> +[      ]+8:[   ]+fef3fc8b[     ]+cv.bneimm[    ]+t2,15,0 +<foo>
> diff --git a/gas/testsuite/gas/riscv/cv-bi-bneimm.s
> b/gas/testsuite/gas/riscv/cv-bi-bneimm.s
> new file mode 100644
> index 00000000000..8014e6a8a4f
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-bneimm.s
> @@ -0,0 +1,4 @@
> +foo:
> +       cv.bneimm t0, -16, foo
> +       cv.bneimm t4, 5, foo
> +       cv.bneimm t2, 15, foo
> diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-march.d
> b/gas/testsuite/gas/riscv/cv-bi-fail-march.d
> new file mode 100644
> index 00000000000..7a24146afe2
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-fail-march.d
> @@ -0,0 +1,3 @@
> +#as: -march=rv32i
> +#source: cv-bi-fail-march.s
> +#error_output: cv-bi-fail-march.l
> diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-march.l
> b/gas/testsuite/gas/riscv/cv-bi-fail-march.l
> new file mode 100644
> index 00000000000..c351c64d414
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-fail-march.l
> @@ -0,0 +1,3 @@
> +.*: Assembler messages:
> +.*: Error: unrecognized opcode `cv.beqimm t2,1,foo', extension `xcvbi'
> required
> +.*: Error: unrecognized opcode `cv.bneimm t2,1,foo', extension `xcvbi'
> required
> diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-march.s
> b/gas/testsuite/gas/riscv/cv-bi-fail-march.s
> new file mode 100644
> index 00000000000..b7fa16de240
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-fail-march.s
> @@ -0,0 +1,5 @@
> +# Absence of xcorev or xcorevbi march option disables all CORE-V
> +# immediate branching extensions.
> +foo:
> +       cv.beqimm t2, 1, foo
> +       cv.bneimm t2, 1, foo
> diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.d
> b/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.d
> new file mode 100644
> index 00000000000..cc73fdd6492
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.d
> @@ -0,0 +1,3 @@
> +#as: -march=rv32i_xcvbi
> +#source: cv-bi-fail-operand-01.s
> +#error_output: cv-bi-fail-operand-01.l
> diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.l
> b/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.l
> new file mode 100644
> index 00000000000..c76c5139429
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.l
> @@ -0,0 +1,3 @@
> +.*: Assembler messages:
> +.*: Error: illegal operands `cv.beqimm 20,10,foo'
> +.*: Error: illegal operands `cv.bneimm 8,-4,foo'
> diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.s
> b/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.s
> new file mode 100644
> index 00000000000..7c529d4d045
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.s
> @@ -0,0 +1,4 @@
> +# Comparison target must be a register
> +foo:
> +       cv.beqimm 20, 10, foo
> +       cv.bneimm 8, -4, foo
> diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.d
> b/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.d
> new file mode 100644
> index 00000000000..39741b9ed2b
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.d
> @@ -0,0 +1,3 @@
> +#as: -march=rv32i_xcvbi
> +#source: cv-bi-fail-operand-02.s
> +#error_output: cv-bi-fail-operand-02.l
> diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.l
> b/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.l
> new file mode 100644
> index 00000000000..7c766fb072a
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.l
> @@ -0,0 +1,3 @@
> +.*: Assembler messages:
> +.*: Error: instruction cv.beqimm requires absolute expression
> +.*: Error: instruction cv.bneimm requires absolute expression
> diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.s
> b/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.s
> new file mode 100644
> index 00000000000..5c8874cb9ac
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.s
> @@ -0,0 +1,4 @@
> +# Comparison value must be an immediate
> +foo:
> +       cv.beqimm t0, t1, foo
> +       cv.bneimm t3, t4, foo
> diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.d
> b/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.d
> new file mode 100644
> index 00000000000..141efdeacc6
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.d
> @@ -0,0 +1,3 @@
> +#as: -march=rv32i_xcvbi
> +#source: cv-bi-fail-operand-03.s
> +#error_output: cv-bi-fail-operand-03.l
> diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.l
> b/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.l
> new file mode 100644
> index 00000000000..af8ebce1284
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.l
> @@ -0,0 +1,9 @@
> +.*: Assembler messages:
> +.*: Error: illegal operands `cv.beqimm t0,-17,foo'
> +.*: Error: illegal operands `cv.beqimm t2,-32,foo'
> +.*: Error: illegal operands `cv.beqimm t4,16,foo'
> +.*: Error: illegal operands `cv.beqimm t3,44,foo'
> +.*: Error: illegal operands `cv.bneimm t0,-17,foo'
> +.*: Error: illegal operands `cv.bneimm t2,-32,foo'
> +.*: Error: illegal operands `cv.bneimm t4,16,foo'
> +.*: Error: illegal operands `cv.bneimm t3,44,foo'
> diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.s
> b/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.s
> new file mode 100644
> index 00000000000..9c7f67b4aed
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.s
> @@ -0,0 +1,10 @@
> +# Comparison value must be an immediate in range [-16, +15]
> +foo:
> +       cv.beqimm t0, -17, foo
> +       cv.beqimm t2, -32, foo
> +       cv.beqimm t4, 16, foo
> +       cv.beqimm t3, 44, foo
> +       cv.bneimm t0, -17, foo
> +       cv.bneimm t2, -32, foo
> +       cv.bneimm t4, 16, foo
> +       cv.bneimm t3, 44, foo
> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
> index 36eb3b5e723..596fad4000f 100644
> --- a/include/opcode/riscv-opc.h
> +++ b/include/opcode/riscv-opc.h
> @@ -2427,6 +2427,11 @@
>  /* Vendor-specific (CORE-V) Xcvelw instructions. */
>  #define MATCH_CV_ELW 0x600b
>  #define MASK_CV_ELW 0x707f
> +/* Vendor-specific (CORE-V) Xcvbi instructions. */
> +#define MATCH_CV_BNEIMM 0x700b
> +#define MASK_CV_BNEIMM 0x707f
> +#define MATCH_CV_BEQIMM 0x600b
> +#define MASK_CV_BEQIMM 0x707f
>  /* Vendor-specific (T-Head) XTheadBa instructions.  */
>  #define MATCH_TH_ADDSL 0x0000100b
>  #define MASK_TH_ADDSL 0xf800707f
> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> index e385bf4ea7a..c15a90dd9b2 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -55,6 +55,7 @@ static inline unsigned int riscv_insn_length (insn_t
> insn)
>  #define RV_X(x, s, n)  (((x) >> (s)) & ((1 << (n)) - 1))
>  #define RV_IMM_SIGN(x) (-(((x) >> 31) & 1))
>  #define RV_X_SIGNED(x, s, n) (RV_X(x, s, n) | ((-(RV_X(x, (s + n - 1),
> 1))) << (n)))
> +#define RV_IMM_SIGN_N(x, s, n) (-(((x) >> ((s) + (n) - 1)) & 1))
>
>  #define EXTRACT_ITYPE_IMM(x) \
>    (RV_X(x, 20, 12) | (RV_IMM_SIGN(x) << 12))
> @@ -117,6 +118,8 @@ static inline unsigned int riscv_insn_length (insn_t
> insn)
>    (RV_X(x, 20, 5))
>  #define EXTRACT_CV_IS3_UIMM5(x) \
>    (RV_X(x, 25, 5))
> +#define EXTRACT_CV_BI_IMM5(x) \
> +  (RV_X(x, 20, 5) | (RV_IMM_SIGN_N(x, 20, 5) << 5))
>
>  #define ENCODE_ITYPE_IMM(x) \
>    (RV_X(x, 0, 12) << 20)
> @@ -472,6 +475,7 @@ enum riscv_insn_class
>    INSN_CLASS_XCVMAC,
>    INSN_CLASS_XCVALU,
>    INSN_CLASS_XCVELW,
> +  INSN_CLASS_XCVBI,
>    INSN_CLASS_XTHEADBA,
>    INSN_CLASS_XTHEADBB,
>    INSN_CLASS_XTHEADBS,
> diff --git a/ld/testsuite/ld-riscv-elf/cv-bi-beqimm.d
> b/ld/testsuite/ld-riscv-elf/cv-bi-beqimm.d
> new file mode 100644
> index 00000000000..b50d3846c1c
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/cv-bi-beqimm.d
> @@ -0,0 +1,21 @@
> +#name: beqimm relocation
> +#source: cv-bi-beqimm.s
> +#as: -march=rv32i_xcvbi
> +#ld: -melf32lriscv
> +#objdump: -dr
> +
> +.*:     file format .*
> +
> +
> +Disassembly of section \.text:
> +
> +.* <func>:
> +.*:[[:space:]]+00008067[[:space:]]+ret
> +
> +.* <_start>:
>
> +.*:[[:space:]]+0102e40b[[:space:]]+cv.beqimm[[:space:]]+t0,-16,.*[[:space:]]+<L2>
> +.*:[[:space:]]+ff9ff0ef[[:space:]]+jal[[:space:]]+10074[[:space:]]+<func>
> +
> +.* <L2>:
> +.*:[[:space:]]+00000013[[:space:]]+nop
> +#pass
> diff --git a/ld/testsuite/ld-riscv-elf/cv-bi-beqimm.s
> b/ld/testsuite/ld-riscv-elf/cv-bi-beqimm.s
> new file mode 100644
> index 00000000000..88a6b293e69
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/cv-bi-beqimm.s
> @@ -0,0 +1,11 @@
> +        .option nopic
> +        .text
> +        .align 1
> +        .globl _start
> +        .type _start, @function
> +
> +func:   ret
> +_start:
> +        cv.beqimm       t0, -16, L2
> +        call func
> +L2:     nop
> diff --git a/ld/testsuite/ld-riscv-elf/cv-bi-bneimm.d
> b/ld/testsuite/ld-riscv-elf/cv-bi-bneimm.d
> new file mode 100644
> index 00000000000..52231a14b71
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/cv-bi-bneimm.d
> @@ -0,0 +1,21 @@
> +#name: bneimm relocation
> +#source: cv-bi-bneimm.s
> +#as: -march=rv32i_xcvbi
> +#ld: -melf32lriscv
> +#objdump: -dr
> +
> +.*:     file format .*
> +
> +
> +Disassembly of section \.text:
> +
> +.* <func>:
> +.*:[[:space:]]+00008067[[:space:]]+ret
> +
> +.* <_start>:
>
> +.*:[[:space:]]+0102f40b[[:space:]]+cv.bneimm[[:space:]]+t0,-16,.*[[:space:]]+<L2>
> +.*:[[:space:]]+ff9ff0ef[[:space:]]+jal[[:space:]]+10074[[:space:]]+<func>
> +
> +.* <L2>:
> +.*:[[:space:]]+00000013[[:space:]]+nop
> +#pass
> diff --git a/ld/testsuite/ld-riscv-elf/cv-bi-bneimm.s
> b/ld/testsuite/ld-riscv-elf/cv-bi-bneimm.s
> new file mode 100644
> index 00000000000..0f514f02e1b
> --- /dev/null
> +++ b/ld/testsuite/ld-riscv-elf/cv-bi-bneimm.s
> @@ -0,0 +1,11 @@
> +        .option nopic
> +        .text
> +        .align 1
> +        .globl _start
> +        .type _start, @function
> +
> +func:   ret
> +_start:
> +        cv.bneimm       t0, -16, L2
> +        call func
> +L2:     nop
> diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> index 7e1281d826b..b9b415a1088 100644
> --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
> @@ -173,6 +173,8 @@ if [istarget "riscv*-*-*"] {
>      run_dump_test "attr-phdr"
>      run_dump_test "relax-max-align-gp"
>      run_dump_test "uleb128"
> +    run_dump_test "cv-bi-bneimm"
> +    run_dump_test "cv-bi-beqimm"
>      run_dump_test "pr31179"
>      run_dump_test "pr31179-r"
>      run_ld_link_tests [list \
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index 3019b9a5130..57497c6f8dd 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -720,6 +720,10 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma
> pc, disassemble_info *info
>                     print (info->stream, dis_style_immediate, "%d",
>                         ((int) EXTRACT_CV_IS3_UIMM5 (l)));
>                     break;
> +                 case '4':
> +                   print (info->stream, dis_style_immediate, "%d",
> +                       ((int) EXTRACT_CV_BI_IMM5 (l)));
> +                   break;
>                   default:
>                     goto undefined_modifier;
>                 }
> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> index 5941621f25d..301f9dad216 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -2115,6 +2115,10 @@ const struct riscv_opcode riscv_opcodes[] =
>  /* Vendor-specific (CORE-V) Xcvelw instructions.  */
>  {"cv.elw", 0, INSN_CLASS_XCVELW, "d,o(s)",  MATCH_CV_ELW, MASK_CV_ELW,
> match_opcode, 0},
>
> +/* Vendor-specific (CORE-V) Xcvbi instructions.  */
> +{"cv.beqimm", 0, INSN_CLASS_XCVBI, "s,Xc4,p", MATCH_CV_BEQIMM,
> MASK_CV_BEQIMM, match_opcode, 0},
> +{"cv.bneimm", 0, INSN_CLASS_XCVBI, "s,Xc4,p", MATCH_CV_BNEIMM,
> MASK_CV_BNEIMM, match_opcode, 0},
> +
>  /* Vendor-specific (T-Head) XTheadBa instructions.  */
>  {"th.addsl",    0, INSN_CLASS_XTHEADBA,    "d,s,t,Xtu2@25",
>  MATCH_TH_ADDSL,    MASK_TH_ADDSL,    match_opcode, 0},
>
> --
> 2.34.1
>
>
  

Patch

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index b8e64a17da0..646f1eddb70 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1370,6 +1370,7 @@  static struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
   {"xcvmac",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xcvalu",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xcvelw",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
+  {"xcvbi",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xtheadba",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xtheadbb",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xtheadbs",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
@@ -2579,6 +2580,8 @@  riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return riscv_subset_supports (rps, "xcvalu");
     case INSN_CLASS_XCVELW:
       return riscv_subset_supports (rps, "xcvelw");
+    case INSN_CLASS_XCVBI:
+      return riscv_subset_supports (rps, "xcvbi");
     case INSN_CLASS_XTHEADBA:
       return riscv_subset_supports (rps, "xtheadba");
     case INSN_CLASS_XTHEADBB:
@@ -2833,6 +2836,8 @@  riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return "xcvalu";
     case INSN_CLASS_XCVELW:
       return "xcvelw";
+    case INSN_CLASS_XCVBI:
+      return "xcvbi";
     case INSN_CLASS_XTHEADBA:
       return "xtheadba";
     case INSN_CLASS_XTHEADBB:
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index a4161420128..77c42e5d8f4 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1501,7 +1501,7 @@  validate_riscv_insn (const struct riscv_opcode *opc, int length)
 	      switch (*++oparg)
 		{
 		  case '2':
-		    /* ls2[4:0] */
+		  case '4':
 		    used_bits |= ENCODE_CV_IS2_UIMM5 (-1U);
 		    break;
 		  case '3':
@@ -3770,6 +3770,16 @@  riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 			ip->insn_opcode
 			    |= ENCODE_CV_IS3_UIMM5 (imm_expr->X_add_number);
 			continue;
+		      case '4':
+			my_getExpression (imm_expr, asarg);
+			check_absolute_expr (ip, imm_expr, FALSE);
+			asarg = expr_parse_end;
+			if (imm_expr->X_add_number < -16
+			    || imm_expr->X_add_number > 15)
+			  break;
+			ip->insn_opcode
+			    |= ENCODE_CV_IS2_UIMM5 (imm_expr->X_add_number);
+			continue;
 		      default:
 			goto unknown_riscv_ip_operand;
 		    }
diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
index d1712b578a0..d983f9b7bba 100644
--- a/gas/doc/c-riscv.texi
+++ b/gas/doc/c-riscv.texi
@@ -755,6 +755,11 @@  The Xcvelw extension provides instructions for event load word operations.
 
 It is documented in @url{https://docs.openhwgroup.org/projects/cv32e40p-user-manual/en/latest/instruction_set_extensions.html}
 
+@item Xcvbi
+The Xcvbi extension provides instructions for branch immediate operations.
+
+It is documented in @url{https://docs.openhwgroup.org/projects/cv32e40p-user-manual/en/latest/instruction_set_extensions.html}
+
 @item XTheadBa
 The XTheadBa extension provides instructions for address calculations.
 
diff --git a/gas/testsuite/gas/riscv/cv-bi-beqimm.d b/gas/testsuite/gas/riscv/cv-bi-beqimm.d
new file mode 100644
index 00000000000..97ef57d91cc
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-beqimm.d
@@ -0,0 +1,12 @@ 
+#as: -march=rv32i_xcvbi
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <foo>:
+[ 	]+0:[ 	]+0102e00b[ 	]+cv.beqimm[ 	]+t0,-16,0 +<foo>
+[ 	]+4:[ 	]+fe5eee8b[ 	]+cv.beqimm[ 	]+t4,5,0 +<foo>
+[ 	]+8:[ 	]+fef3ec8b[ 	]+cv.beqimm[ 	]+t2,15,0 +<foo>
diff --git a/gas/testsuite/gas/riscv/cv-bi-beqimm.s b/gas/testsuite/gas/riscv/cv-bi-beqimm.s
new file mode 100644
index 00000000000..7fbb8f27515
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-beqimm.s
@@ -0,0 +1,4 @@ 
+foo:
+	cv.beqimm t0, -16, foo
+	cv.beqimm t4, 5, foo
+	cv.beqimm t2, 15, foo
diff --git a/gas/testsuite/gas/riscv/cv-bi-bneimm.d b/gas/testsuite/gas/riscv/cv-bi-bneimm.d
new file mode 100644
index 00000000000..7dddf408107
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-bneimm.d
@@ -0,0 +1,12 @@ 
+#as: -march=rv32i_xcvbi
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <foo>:
+[ 	]+0:[ 	]+0102f00b[ 	]+cv.bneimm[ 	]+t0,-16,0 +<foo>
+[ 	]+4:[ 	]+fe5efe8b[ 	]+cv.bneimm[ 	]+t4,5,0 +<foo>
+[ 	]+8:[ 	]+fef3fc8b[ 	]+cv.bneimm[ 	]+t2,15,0 +<foo>
diff --git a/gas/testsuite/gas/riscv/cv-bi-bneimm.s b/gas/testsuite/gas/riscv/cv-bi-bneimm.s
new file mode 100644
index 00000000000..8014e6a8a4f
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-bneimm.s
@@ -0,0 +1,4 @@ 
+foo:
+	cv.bneimm t0, -16, foo
+	cv.bneimm t4, 5, foo
+	cv.bneimm t2, 15, foo
diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-march.d b/gas/testsuite/gas/riscv/cv-bi-fail-march.d
new file mode 100644
index 00000000000..7a24146afe2
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-fail-march.d
@@ -0,0 +1,3 @@ 
+#as: -march=rv32i
+#source: cv-bi-fail-march.s
+#error_output: cv-bi-fail-march.l
diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-march.l b/gas/testsuite/gas/riscv/cv-bi-fail-march.l
new file mode 100644
index 00000000000..c351c64d414
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-fail-march.l
@@ -0,0 +1,3 @@ 
+.*: Assembler messages:
+.*: Error: unrecognized opcode `cv.beqimm t2,1,foo', extension `xcvbi' required
+.*: Error: unrecognized opcode `cv.bneimm t2,1,foo', extension `xcvbi' required
diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-march.s b/gas/testsuite/gas/riscv/cv-bi-fail-march.s
new file mode 100644
index 00000000000..b7fa16de240
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-fail-march.s
@@ -0,0 +1,5 @@ 
+# Absence of xcorev or xcorevbi march option disables all CORE-V
+# immediate branching extensions.
+foo:
+	cv.beqimm t2, 1, foo
+	cv.bneimm t2, 1, foo
diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.d b/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.d
new file mode 100644
index 00000000000..cc73fdd6492
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.d
@@ -0,0 +1,3 @@ 
+#as: -march=rv32i_xcvbi
+#source: cv-bi-fail-operand-01.s
+#error_output: cv-bi-fail-operand-01.l
diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.l b/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.l
new file mode 100644
index 00000000000..c76c5139429
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.l
@@ -0,0 +1,3 @@ 
+.*: Assembler messages:
+.*: Error: illegal operands `cv.beqimm 20,10,foo'
+.*: Error: illegal operands `cv.bneimm 8,-4,foo'
diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.s b/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.s
new file mode 100644
index 00000000000..7c529d4d045
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-01.s
@@ -0,0 +1,4 @@ 
+# Comparison target must be a register
+foo:
+	cv.beqimm 20, 10, foo
+	cv.bneimm 8, -4, foo
diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.d b/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.d
new file mode 100644
index 00000000000..39741b9ed2b
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.d
@@ -0,0 +1,3 @@ 
+#as: -march=rv32i_xcvbi
+#source: cv-bi-fail-operand-02.s
+#error_output: cv-bi-fail-operand-02.l
diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.l b/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.l
new file mode 100644
index 00000000000..7c766fb072a
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.l
@@ -0,0 +1,3 @@ 
+.*: Assembler messages:
+.*: Error: instruction cv.beqimm requires absolute expression
+.*: Error: instruction cv.bneimm requires absolute expression
diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.s b/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.s
new file mode 100644
index 00000000000..5c8874cb9ac
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-02.s
@@ -0,0 +1,4 @@ 
+# Comparison value must be an immediate
+foo:
+	cv.beqimm t0, t1, foo
+	cv.bneimm t3, t4, foo
diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.d b/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.d
new file mode 100644
index 00000000000..141efdeacc6
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.d
@@ -0,0 +1,3 @@ 
+#as: -march=rv32i_xcvbi
+#source: cv-bi-fail-operand-03.s
+#error_output: cv-bi-fail-operand-03.l
diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.l b/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.l
new file mode 100644
index 00000000000..af8ebce1284
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.l
@@ -0,0 +1,9 @@ 
+.*: Assembler messages:
+.*: Error: illegal operands `cv.beqimm t0,-17,foo'
+.*: Error: illegal operands `cv.beqimm t2,-32,foo'
+.*: Error: illegal operands `cv.beqimm t4,16,foo'
+.*: Error: illegal operands `cv.beqimm t3,44,foo'
+.*: Error: illegal operands `cv.bneimm t0,-17,foo'
+.*: Error: illegal operands `cv.bneimm t2,-32,foo'
+.*: Error: illegal operands `cv.bneimm t4,16,foo'
+.*: Error: illegal operands `cv.bneimm t3,44,foo'
diff --git a/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.s b/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.s
new file mode 100644
index 00000000000..9c7f67b4aed
--- /dev/null
+++ b/gas/testsuite/gas/riscv/cv-bi-fail-operand-03.s
@@ -0,0 +1,10 @@ 
+# Comparison value must be an immediate in range [-16, +15]
+foo:
+	cv.beqimm t0, -17, foo
+	cv.beqimm t2, -32, foo
+	cv.beqimm t4, 16, foo
+	cv.beqimm t3, 44, foo
+	cv.bneimm t0, -17, foo
+	cv.bneimm t2, -32, foo
+	cv.bneimm t4, 16, foo
+	cv.bneimm t3, 44, foo
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 36eb3b5e723..596fad4000f 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -2427,6 +2427,11 @@ 
 /* Vendor-specific (CORE-V) Xcvelw instructions. */
 #define MATCH_CV_ELW 0x600b
 #define MASK_CV_ELW 0x707f
+/* Vendor-specific (CORE-V) Xcvbi instructions. */
+#define MATCH_CV_BNEIMM 0x700b
+#define MASK_CV_BNEIMM 0x707f
+#define MATCH_CV_BEQIMM 0x600b
+#define MASK_CV_BEQIMM 0x707f
 /* Vendor-specific (T-Head) XTheadBa instructions.  */
 #define MATCH_TH_ADDSL 0x0000100b
 #define MASK_TH_ADDSL 0xf800707f
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index e385bf4ea7a..c15a90dd9b2 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -55,6 +55,7 @@  static inline unsigned int riscv_insn_length (insn_t insn)
 #define RV_X(x, s, n)  (((x) >> (s)) & ((1 << (n)) - 1))
 #define RV_IMM_SIGN(x) (-(((x) >> 31) & 1))
 #define RV_X_SIGNED(x, s, n) (RV_X(x, s, n) | ((-(RV_X(x, (s + n - 1), 1))) << (n)))
+#define RV_IMM_SIGN_N(x, s, n) (-(((x) >> ((s) + (n) - 1)) & 1))
 
 #define EXTRACT_ITYPE_IMM(x) \
   (RV_X(x, 20, 12) | (RV_IMM_SIGN(x) << 12))
@@ -117,6 +118,8 @@  static inline unsigned int riscv_insn_length (insn_t insn)
   (RV_X(x, 20, 5))
 #define EXTRACT_CV_IS3_UIMM5(x) \
   (RV_X(x, 25, 5))
+#define EXTRACT_CV_BI_IMM5(x) \
+  (RV_X(x, 20, 5) | (RV_IMM_SIGN_N(x, 20, 5) << 5))
 
 #define ENCODE_ITYPE_IMM(x) \
   (RV_X(x, 0, 12) << 20)
@@ -472,6 +475,7 @@  enum riscv_insn_class
   INSN_CLASS_XCVMAC,
   INSN_CLASS_XCVALU,
   INSN_CLASS_XCVELW,
+  INSN_CLASS_XCVBI,
   INSN_CLASS_XTHEADBA,
   INSN_CLASS_XTHEADBB,
   INSN_CLASS_XTHEADBS,
diff --git a/ld/testsuite/ld-riscv-elf/cv-bi-beqimm.d b/ld/testsuite/ld-riscv-elf/cv-bi-beqimm.d
new file mode 100644
index 00000000000..b50d3846c1c
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/cv-bi-beqimm.d
@@ -0,0 +1,21 @@ 
+#name: beqimm relocation
+#source: cv-bi-beqimm.s
+#as: -march=rv32i_xcvbi
+#ld: -melf32lriscv
+#objdump: -dr
+
+.*:     file format .*
+
+
+Disassembly of section \.text:
+
+.* <func>:
+.*:[[:space:]]+00008067[[:space:]]+ret
+
+.* <_start>:
+.*:[[:space:]]+0102e40b[[:space:]]+cv.beqimm[[:space:]]+t0,-16,.*[[:space:]]+<L2>
+.*:[[:space:]]+ff9ff0ef[[:space:]]+jal[[:space:]]+10074[[:space:]]+<func>
+
+.* <L2>:
+.*:[[:space:]]+00000013[[:space:]]+nop
+#pass
diff --git a/ld/testsuite/ld-riscv-elf/cv-bi-beqimm.s b/ld/testsuite/ld-riscv-elf/cv-bi-beqimm.s
new file mode 100644
index 00000000000..88a6b293e69
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/cv-bi-beqimm.s
@@ -0,0 +1,11 @@ 
+        .option nopic
+        .text
+        .align 1
+        .globl _start
+        .type _start, @function
+
+func:   ret
+_start:
+        cv.beqimm       t0, -16, L2
+        call func
+L2:     nop
diff --git a/ld/testsuite/ld-riscv-elf/cv-bi-bneimm.d b/ld/testsuite/ld-riscv-elf/cv-bi-bneimm.d
new file mode 100644
index 00000000000..52231a14b71
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/cv-bi-bneimm.d
@@ -0,0 +1,21 @@ 
+#name: bneimm relocation
+#source: cv-bi-bneimm.s
+#as: -march=rv32i_xcvbi
+#ld: -melf32lriscv
+#objdump: -dr
+
+.*:     file format .*
+
+
+Disassembly of section \.text:
+
+.* <func>:
+.*:[[:space:]]+00008067[[:space:]]+ret
+
+.* <_start>:
+.*:[[:space:]]+0102f40b[[:space:]]+cv.bneimm[[:space:]]+t0,-16,.*[[:space:]]+<L2>
+.*:[[:space:]]+ff9ff0ef[[:space:]]+jal[[:space:]]+10074[[:space:]]+<func>
+
+.* <L2>:
+.*:[[:space:]]+00000013[[:space:]]+nop
+#pass
diff --git a/ld/testsuite/ld-riscv-elf/cv-bi-bneimm.s b/ld/testsuite/ld-riscv-elf/cv-bi-bneimm.s
new file mode 100644
index 00000000000..0f514f02e1b
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/cv-bi-bneimm.s
@@ -0,0 +1,11 @@ 
+        .option nopic
+        .text
+        .align 1
+        .globl _start
+        .type _start, @function
+
+func:   ret
+_start:
+        cv.bneimm       t0, -16, L2
+        call func
+L2:     nop
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index 7e1281d826b..b9b415a1088 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -173,6 +173,8 @@  if [istarget "riscv*-*-*"] {
     run_dump_test "attr-phdr"
     run_dump_test "relax-max-align-gp"
     run_dump_test "uleb128"
+    run_dump_test "cv-bi-bneimm"
+    run_dump_test "cv-bi-beqimm"
     run_dump_test "pr31179"
     run_dump_test "pr31179-r"
     run_ld_link_tests [list \
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 3019b9a5130..57497c6f8dd 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -720,6 +720,10 @@  print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 		    print (info->stream, dis_style_immediate, "%d",
 			((int) EXTRACT_CV_IS3_UIMM5 (l)));
 		    break;
+		  case '4':
+		    print (info->stream, dis_style_immediate, "%d",
+			((int) EXTRACT_CV_BI_IMM5 (l)));
+		    break;
 		  default:
 		    goto undefined_modifier;
 		}
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 5941621f25d..301f9dad216 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -2115,6 +2115,10 @@  const struct riscv_opcode riscv_opcodes[] =
 /* Vendor-specific (CORE-V) Xcvelw instructions.  */
 {"cv.elw", 0, INSN_CLASS_XCVELW, "d,o(s)",  MATCH_CV_ELW, MASK_CV_ELW, match_opcode, 0},
 
+/* Vendor-specific (CORE-V) Xcvbi instructions.  */
+{"cv.beqimm", 0, INSN_CLASS_XCVBI, "s,Xc4,p", MATCH_CV_BEQIMM, MASK_CV_BEQIMM, match_opcode, 0},
+{"cv.bneimm", 0, INSN_CLASS_XCVBI, "s,Xc4,p", MATCH_CV_BNEIMM, MASK_CV_BNEIMM, match_opcode, 0},
+
 /* Vendor-specific (T-Head) XTheadBa instructions.  */
 {"th.addsl",    0, INSN_CLASS_XTHEADBA,    "d,s,t,Xtu2@25",   MATCH_TH_ADDSL,    MASK_TH_ADDSL,    match_opcode, 0},