[v3,3/4] RISC-V: Add support for Zbs instructions

Message ID 20211006202647.328777-3-philipp.tomsich@vrull.eu
State New
Headers show
Series
  • [v3,1/4] RISC-V: Split Zb[abc] into commented sections
Related show

Commit Message

Philipp Tomsich Oct. 6, 2021, 8:26 p.m.
This change adds the Zbs instructions from the Zbs 1.0.0 specification.
See
  https://github.com/riscv/riscv-bitmanip/releases/tag/1.0.0
for the frozen specification.

2021-01-09  Philipp Tomsich  <philipp.tomsich@vrull.eu>

    bfd/
	* elfxx-riscv.c (riscv_supported_std_z_ext): Added zbs.
    gas/
	* config/tc-riscv.c (riscv_multi_subset_supports): Handle INSN_CLASS_ZBS.
	* testsuite/gas/riscv/b-ext.d: Test Zbs instructions.
	* testsuite/gas/riscv/b-ext.s: Likewise.
	* testsuite/gas/riscv/b-ext-64.d: Likewise.
	* testsuite/gas/riscv/b-ext-64.s: Likewise.
    include/
	* opcode/riscv-opc.h: Added MASK/MATCH/DECLARE_INSN for Zbs.
	* opcode/riscv.h (riscv_insn_class): Added INSN_CLASS_ZBS.
    opcodes/
	* riscv-opc.c (riscv_supported_std_z_ext): Add zbs.

Signed-off-by: Philipp Tomsich <philipp.tomsich@vrull.eu>


---

Changes in v3:
- Updated to 1.0.0 specification and rebased to master

 bfd/elfxx-riscv.c                  |  1 +
 gas/config/tc-riscv.c              |  3 +++
 gas/testsuite/gas/riscv/b-ext-64.d | 18 +++++++++++++++++-
 gas/testsuite/gas/riscv/b-ext-64.s | 16 ++++++++++++++++
 gas/testsuite/gas/riscv/b-ext.d    | 14 +++++++++++++-
 gas/testsuite/gas/riscv/b-ext.s    | 12 ++++++++++++
 include/opcode/riscv-opc.h         | 24 ++++++++++++++++++++++++
 include/opcode/riscv.h             |  1 +
 opcodes/riscv-opc.c                |  9 +++++++++
 9 files changed, 96 insertions(+), 2 deletions(-)

-- 
2.25.1

Comments

Nelson Chu Oct. 7, 2021, 4:02 a.m. | #1
LGTM, thanks.

Nelson

On Thu, Oct 7, 2021 at 4:28 AM Philipp Tomsich <philipp.tomsich@vrull.eu> wrote:
>

> This change adds the Zbs instructions from the Zbs 1.0.0 specification.

> See

>   https://github.com/riscv/riscv-bitmanip/releases/tag/1.0.0

> for the frozen specification.

>

> 2021-01-09  Philipp Tomsich  <philipp.tomsich@vrull.eu>

>

>     bfd/

>         * elfxx-riscv.c (riscv_supported_std_z_ext): Added zbs.

>     gas/

>         * config/tc-riscv.c (riscv_multi_subset_supports): Handle INSN_CLASS_ZBS.

>         * testsuite/gas/riscv/b-ext.d: Test Zbs instructions.

>         * testsuite/gas/riscv/b-ext.s: Likewise.

>         * testsuite/gas/riscv/b-ext-64.d: Likewise.

>         * testsuite/gas/riscv/b-ext-64.s: Likewise.

>     include/

>         * opcode/riscv-opc.h: Added MASK/MATCH/DECLARE_INSN for Zbs.

>         * opcode/riscv.h (riscv_insn_class): Added INSN_CLASS_ZBS.

>     opcodes/

>         * riscv-opc.c (riscv_supported_std_z_ext): Add zbs.

>

> Signed-off-by: Philipp Tomsich <philipp.tomsich@vrull.eu>

>

> ---

>

> Changes in v3:

> - Updated to 1.0.0 specification and rebased to master

>

>  bfd/elfxx-riscv.c                  |  1 +

>  gas/config/tc-riscv.c              |  3 +++

>  gas/testsuite/gas/riscv/b-ext-64.d | 18 +++++++++++++++++-

>  gas/testsuite/gas/riscv/b-ext-64.s | 16 ++++++++++++++++

>  gas/testsuite/gas/riscv/b-ext.d    | 14 +++++++++++++-

>  gas/testsuite/gas/riscv/b-ext.s    | 12 ++++++++++++

>  include/opcode/riscv-opc.h         | 24 ++++++++++++++++++++++++

>  include/opcode/riscv.h             |  1 +

>  opcodes/riscv-opc.c                |  9 +++++++++

>  9 files changed, 96 insertions(+), 2 deletions(-)

>

> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c

> index 39a7d693469..cdb4fa0996a 100644

> --- a/bfd/elfxx-riscv.c

> +++ b/bfd/elfxx-riscv.c

> @@ -1145,6 +1145,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =

>    {"zbb",              ISA_SPEC_CLASS_DRAFT,           1, 0,  0 },

>    {"zba",              ISA_SPEC_CLASS_DRAFT,           1, 0,  0 },

>    {"zbc",              ISA_SPEC_CLASS_DRAFT,           1, 0,  0 },

> +  {"zbs",               ISA_SPEC_CLASS_DRAFT,           1, 0,  0 },

>    {NULL, 0, 0, 0, 0}

>  };

>

> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c

> index e7b733a4e6d..f7e0c929aa0 100644

> --- a/gas/config/tc-riscv.c

> +++ b/gas/config/tc-riscv.c

> @@ -283,6 +283,9 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class)

>      case INSN_CLASS_ZBC:

>        return riscv_subset_supports ("zbc");

>

> +    case INSN_CLASS_ZBS:

> +      return riscv_subset_supports ("zbs");

> +

>      default:

>        as_fatal ("internal: unreachable");

>        return false;

> diff --git a/gas/testsuite/gas/riscv/b-ext-64.d b/gas/testsuite/gas/riscv/b-ext-64.d

> index f4a7abf02d7..339fa20a367 100644

> --- a/gas/testsuite/gas/riscv/b-ext-64.d

> +++ b/gas/testsuite/gas/riscv/b-ext-64.d

> @@ -1,4 +1,4 @@

> -#as: -march=rv64i_zba_zbb_zbc

> +#as: -march=rv64i_zba_zbb_zbc_zbs

>  #source: b-ext-64.s

>  #objdump: -d

>

> @@ -46,3 +46,19 @@ Disassembly of section .text:

>  [      ]+8c:[  ]+08c5853b[     ]+add.uw[       ]+a0,a1,a2

>  [      ]+90:[  ]+0805853b[     ]+zext.w[       ]+a0,a1

>  [      ]+94:[  ]+0825951b[     ]+slli.uw[      ]+a0,a1,0x2

> +[      ]+[0-9a-f]+:[   ]+48059513[     ]+bclri[        ]+a0,a1,0x0

> +[      ]+[0-9a-f]+:[   ]+49f59513[     ]+bclri[        ]+a0,a1,0x1f

> +[      ]+[0-9a-f]+:[   ]+28059513[     ]+bseti[        ]+a0,a1,0x0

> +[      ]+[0-9a-f]+:[   ]+29f59513[     ]+bseti[        ]+a0,a1,0x1f

> +[      ]+[0-9a-f]+:[   ]+68059513[     ]+binvi[        ]+a0,a1,0x0

> +[      ]+[0-9a-f]+:[   ]+69f59513[     ]+binvi[        ]+a0,a1,0x1f

> +[      ]+[0-9a-f]+:[   ]+4805d513[     ]+bexti[        ]+a0,a1,0x0

> +[      ]+[0-9a-f]+:[   ]+49f5d513[     ]+bexti[        ]+a0,a1,0x1f

> +[      ]+[0-9a-f]+:[   ]+4bf59513[     ]+bclri[        ]+a0,a1,0x3f

> +[      ]+[0-9a-f]+:[   ]+2bf59513[     ]+bseti[        ]+a0,a1,0x3f

> +[      ]+[0-9a-f]+:[   ]+6bf59513[     ]+binvi[        ]+a0,a1,0x3f

> +[      ]+[0-9a-f]+:[   ]+4bf5d513[     ]+bexti[        ]+a0,a1,0x3f

> +[      ]+[0-9a-f]+:[   ]+48c59533[     ]+bclr[         ]+a0,a1,a2

> +[      ]+[0-9a-f]+:[   ]+28c59533[     ]+bset[         ]+a0,a1,a2

> +[      ]+[0-9a-f]+:[   ]+68c59533[     ]+binv[         ]+a0,a1,a2

> +[      ]+[0-9a-f]+:[   ]+48c5d533[     ]+bext[         ]+a0,a1,a2

> diff --git a/gas/testsuite/gas/riscv/b-ext-64.s b/gas/testsuite/gas/riscv/b-ext-64.s

> index c3ac377f4bd..8ceb2b4fd1c 100644

> --- a/gas/testsuite/gas/riscv/b-ext-64.s

> +++ b/gas/testsuite/gas/riscv/b-ext-64.s

> @@ -37,3 +37,19 @@ target:

>         add.uw  a0, a1, a2

>         zext.w  a0, a1

>         slli.uw a0, a1, 2

> +       bclri   a0, a1, 0

> +       bclri   a0, a1, 31

> +       bseti   a0, a1, 0

> +       bseti   a0, a1, 31

> +       binvi   a0, a1, 0

> +       binvi   a0, a1, 31

> +       bexti   a0, a1, 0

> +       bexti   a0, a1, 31

> +       bclri   a0, a1, 63

> +       bseti   a0, a1, 63

> +       binvi   a0, a1, 63

> +       bexti   a0, a1, 63

> +       bclr    a0, a1, a2

> +       bset    a0, a1, a2

> +       binv    a0, a1, a2

> +       bext    a0, a1, a2

> diff --git a/gas/testsuite/gas/riscv/b-ext.d b/gas/testsuite/gas/riscv/b-ext.d

> index 7410796a3b7..748c218fdd0 100644

> --- a/gas/testsuite/gas/riscv/b-ext.d

> +++ b/gas/testsuite/gas/riscv/b-ext.d

> @@ -1,4 +1,4 @@

> -#as: -march=rv32i_zba_zbb_zbc

> +#as: -march=rv32i_zba_zbb_zbc_zbs

>  #source: b-ext.s

>  #objdump: -d

>

> @@ -33,3 +33,15 @@ Disassembly of section .text:

>  [      ]+58:[  ]+0ac59533[     ]+clmul[        ]+a0,a1,a2

>  [      ]+5c:[  ]+0ac5b533[     ]+clmulh[       ]+a0,a1,a2

>  [      ]+60:[  ]+0ac5a533[     ]+clmulr[       ]+a0,a1,a2

> +[      ]+[0-9a-f]+:[   ]+48059513[     ]+bclri[        ]+a0,a1,0x0

> +[      ]+[0-9a-f]+:[   ]+49f59513[     ]+bclri[        ]+a0,a1,0x1f

> +[      ]+[0-9a-f]+:[   ]+28059513[     ]+bseti[        ]+a0,a1,0x0

> +[      ]+[0-9a-f]+:[   ]+29f59513[     ]+bseti[        ]+a0,a1,0x1f

> +[      ]+[0-9a-f]+:[   ]+68059513[     ]+binvi[        ]+a0,a1,0x0

> +[      ]+[0-9a-f]+:[   ]+69f59513[     ]+binvi[        ]+a0,a1,0x1f

> +[      ]+[0-9a-f]+:[   ]+4805d513[     ]+bexti[        ]+a0,a1,0x0

> +[      ]+[0-9a-f]+:[   ]+49f5d513[     ]+bexti[        ]+a0,a1,0x1f

> +[      ]+[0-9a-f]+:[   ]+48c59533[     ]+bclr[         ]+a0,a1,a2

> +[      ]+[0-9a-f]+:[   ]+28c59533[     ]+bset[         ]+a0,a1,a2

> +[      ]+[0-9a-f]+:[   ]+68c59533[     ]+binv[         ]+a0,a1,a2

> +[      ]+[0-9a-f]+:[   ]+48c5d533[     ]+bext[         ]+a0,a1,a2

> diff --git a/gas/testsuite/gas/riscv/b-ext.s b/gas/testsuite/gas/riscv/b-ext.s

> index 051dafd1719..a13a797f0dc 100644

> --- a/gas/testsuite/gas/riscv/b-ext.s

> +++ b/gas/testsuite/gas/riscv/b-ext.s

> @@ -24,3 +24,15 @@ target:

>         clmul   a0, a1, a2

>         clmulh  a0, a1, a2

>         clmulr  a0, a1, a2

> +       bclri   a0, a1, 0

> +       bclri   a0, a1, 31

> +       bseti   a0, a1, 0

> +       bseti   a0, a1, 31

> +       binvi   a0, a1, 0

> +       binvi   a0, a1, 31

> +       bexti   a0, a1, 0

> +       bexti   a0, a1, 31

> +       bclr    a0, a1, a2

> +       bset    a0, a1, a2

> +       binv    a0, a1, a2

> +       bext    a0, a1, a2

> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h

> index 9999da6241a..45a207da0cd 100644

> --- a/include/opcode/riscv-opc.h

> +++ b/include/opcode/riscv-opc.h

> @@ -495,6 +495,22 @@

>  #define MASK_CLMULH  0xfe00707f

>  #define MATCH_CLMULR 0xa002033

>  #define MASK_CLMULR  0xfe00707f

> +#define MATCH_BCLRI 0x48001013

> +#define MASK_BCLRI  0xfc00707f

> +#define MATCH_BSETI 0x28001013

> +#define MASK_BSETI  0xfc00707f

> +#define MATCH_BINVI 0x68001013

> +#define MASK_BINVI  0xfc00707f

> +#define MATCH_BEXTI 0x48005013

> +#define MASK_BEXTI  0xfc00707f

> +#define MATCH_BCLR  0x48001033

> +#define MASK_BCLR   0xfe00707f

> +#define MATCH_BSET  0x28001033

> +#define MASK_BSET   0xfe00707f

> +#define MATCH_BINV  0x68001033

> +#define MASK_BINV   0xfe00707f

> +#define MATCH_BEXT  0x48005033

> +#define MASK_BEXT   0xfe00707f

>  #define MATCH_FLW 0x2007

>  #define MASK_FLW  0x707f

>  #define MATCH_FLD 0x3007

> @@ -1102,6 +1118,14 @@ DECLARE_INSN(slli_uw, MATCH_SLLI_UW, MASK_SLLI_UW)

>  DECLARE_INSN(clmul, MATCH_CLMUL, MASK_CLMUL)

>  DECLARE_INSN(clmulh, MATCH_CLMULH, MASK_CLMULH)

>  DECLARE_INSN(clmulr, MATCH_CLMULR, MASK_CLMULR)

> +DECLARE_INSN(bclri, MATCH_BCLRI, MASK_BCLRI)

> +DECLARE_INSN(bseti, MATCH_BSETI, MASK_BSETI)

> +DECLARE_INSN(binvi, MATCH_BINVI, MASK_BINVI)

> +DECLARE_INSN(bexti, MATCH_BEXTI, MASK_BEXTI)

> +DECLARE_INSN(bclr, MATCH_BCLR, MASK_BCLR)

> +DECLARE_INSN(bset, MATCH_BSET, MASK_BSET)

> +DECLARE_INSN(binv, MATCH_BINV, MASK_BINV)

> +DECLARE_INSN(bext, MATCH_BEXT, MASK_BEXT)

>  DECLARE_INSN(flw, MATCH_FLW, MASK_FLW)

>  DECLARE_INSN(fld, MATCH_FLD, MASK_FLD)

>  DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ)

> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h

> index a8f47419f75..afcd41ff1dd 100644

> --- a/include/opcode/riscv.h

> +++ b/include/opcode/riscv.h

> @@ -319,6 +319,7 @@ enum riscv_insn_class

>    INSN_CLASS_ZBA,

>    INSN_CLASS_ZBB,

>    INSN_CLASS_ZBC,

> +  INSN_CLASS_ZBS,

>  };

>

>  /* This structure holds information for a particular instruction.  */

> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c

> index e0621503b79..1a4c9f0e4fe 100644

> --- a/opcodes/riscv-opc.c

> +++ b/opcodes/riscv-opc.c

> @@ -833,6 +833,15 @@ const struct riscv_opcode riscv_opcodes[] =

>  {"clmulh",     0, INSN_CLASS_ZBC,  "d,s,t", MATCH_CLMULH, MASK_CLMULH, match_opcode, 0 },

>  {"clmulr",     0, INSN_CLASS_ZBC,  "d,s,t", MATCH_CLMULR, MASK_CLMULR, match_opcode, 0 },

>

> +/* Zbs instructions */

> +{"bclri",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BCLRI, MASK_BCLRI, match_opcode, 0 },

> +{"bseti",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BSETI, MASK_BSETI, match_opcode, 0 },

> +{"binvi",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BINVI, MASK_BINVI, match_opcode, 0 },

> +{"bexti",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BEXTI, MASK_BEXTI, match_opcode, 0 },

> +{"bclr",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BCLR, MASK_BCLR, match_opcode, 0 },

> +{"bset",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BSET, MASK_BSET, match_opcode, 0 },

> +{"binv",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BINV, MASK_BINV, match_opcode, 0 },

> +{"bext",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BEXT, MASK_BEXT, match_opcode, 0 },

>

>  /* Terminate the list.  */

>  {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}

> --

> 2.25.1

>
H.J. Lu via Binutils Oct. 7, 2021, 6:57 a.m. | #2
On 06.10.2021 22:26, Philipp Tomsich wrote:
> --- a/opcodes/riscv-opc.c

> +++ b/opcodes/riscv-opc.c

> @@ -833,6 +833,15 @@ const struct riscv_opcode riscv_opcodes[] =

>  {"clmulh",     0, INSN_CLASS_ZBC,  "d,s,t", MATCH_CLMULH, MASK_CLMULH, match_opcode, 0 },

>  {"clmulr",     0, INSN_CLASS_ZBC,  "d,s,t", MATCH_CLMULR, MASK_CLMULR, match_opcode, 0 },

>  

> +/* Zbs instructions */

> +{"bclri",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BCLRI, MASK_BCLRI, match_opcode, 0 },

> +{"bseti",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BSETI, MASK_BSETI, match_opcode, 0 },

> +{"binvi",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BINVI, MASK_BINVI, match_opcode, 0 },

> +{"bexti",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BEXTI, MASK_BEXTI, match_opcode, 0 },


To be consistent with other insns with immediate operands, shouldn't all
of these have aliases without the i suffix?

Jan

> +{"bclr",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BCLR, MASK_BCLR, match_opcode, 0 },

> +{"bset",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BSET, MASK_BSET, match_opcode, 0 },

> +{"binv",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BINV, MASK_BINV, match_opcode, 0 },

> +{"bext",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BEXT, MASK_BEXT, match_opcode, 0 },

>  

>  /* Terminate the list.  */

>  {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}

>
postmaster@partis.co.uk Oct. 7, 2021, 11:51 a.m. | #3
Delivery is delayed to these recipients or groups:

gary@partis.co.uk<mailto:gary@partis.co.uk>

Subject: Re: [PATCH v3 3/4] RISC-V: Add support for Zbs instructions

This message hasn't been delivered yet. Delivery will continue to be attempted.

The server will keep trying to deliver this message for the next 19 days, 19 hours and 8 minutes. You'll be notified if the message can't be delivered by that time.

Patch

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 39a7d693469..cdb4fa0996a 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1145,6 +1145,7 @@  static struct riscv_supported_ext riscv_supported_std_z_ext[] =
   {"zbb",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zba",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zbc",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
+  {"zbs",               ISA_SPEC_CLASS_DRAFT,           1, 0,  0 },
   {NULL, 0, 0, 0, 0}
 };
 
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index e7b733a4e6d..f7e0c929aa0 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -283,6 +283,9 @@  riscv_multi_subset_supports (enum riscv_insn_class insn_class)
     case INSN_CLASS_ZBC:
       return riscv_subset_supports ("zbc");
 
+    case INSN_CLASS_ZBS:
+      return riscv_subset_supports ("zbs");
+
     default:
       as_fatal ("internal: unreachable");
       return false;
diff --git a/gas/testsuite/gas/riscv/b-ext-64.d b/gas/testsuite/gas/riscv/b-ext-64.d
index f4a7abf02d7..339fa20a367 100644
--- a/gas/testsuite/gas/riscv/b-ext-64.d
+++ b/gas/testsuite/gas/riscv/b-ext-64.d
@@ -1,4 +1,4 @@ 
-#as: -march=rv64i_zba_zbb_zbc
+#as: -march=rv64i_zba_zbb_zbc_zbs
 #source: b-ext-64.s
 #objdump: -d
 
@@ -46,3 +46,19 @@  Disassembly of section .text:
 [ 	]+8c:[ 	]+08c5853b[ 	]+add.uw[ 	]+a0,a1,a2
 [ 	]+90:[ 	]+0805853b[ 	]+zext.w[ 	]+a0,a1
 [ 	]+94:[ 	]+0825951b[ 	]+slli.uw[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+48059513[ 	]+bclri[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f59513[ 	]+bclri[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+28059513[ 	]+bseti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f59513[ 	]+bseti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+68059513[ 	]+binvi[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f59513[ 	]+binvi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+4805d513[ 	]+bexti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f5d513[ 	]+bexti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+4bf59513[ 	]+bclri[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+2bf59513[ 	]+bseti[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+6bf59513[ 	]+binvi[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+4bf5d513[ 	]+bexti[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+48c59533[ 	]+bclr[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+28c59533[ 	]+bset[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+68c59533[ 	]+binv[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5d533[ 	]+bext[ 	]+a0,a1,a2
diff --git a/gas/testsuite/gas/riscv/b-ext-64.s b/gas/testsuite/gas/riscv/b-ext-64.s
index c3ac377f4bd..8ceb2b4fd1c 100644
--- a/gas/testsuite/gas/riscv/b-ext-64.s
+++ b/gas/testsuite/gas/riscv/b-ext-64.s
@@ -37,3 +37,19 @@  target:
 	add.uw	a0, a1, a2
 	zext.w	a0, a1
 	slli.uw	a0, a1, 2
+	bclri   a0, a1, 0
+	bclri   a0, a1, 31
+	bseti   a0, a1, 0
+	bseti   a0, a1, 31
+	binvi   a0, a1, 0
+	binvi   a0, a1, 31
+	bexti   a0, a1, 0
+	bexti   a0, a1, 31
+	bclri   a0, a1, 63
+	bseti   a0, a1, 63
+	binvi   a0, a1, 63
+	bexti   a0, a1, 63
+	bclr    a0, a1, a2
+	bset    a0, a1, a2
+	binv    a0, a1, a2
+	bext    a0, a1, a2
diff --git a/gas/testsuite/gas/riscv/b-ext.d b/gas/testsuite/gas/riscv/b-ext.d
index 7410796a3b7..748c218fdd0 100644
--- a/gas/testsuite/gas/riscv/b-ext.d
+++ b/gas/testsuite/gas/riscv/b-ext.d
@@ -1,4 +1,4 @@ 
-#as: -march=rv32i_zba_zbb_zbc
+#as: -march=rv32i_zba_zbb_zbc_zbs
 #source: b-ext.s
 #objdump: -d
 
@@ -33,3 +33,15 @@  Disassembly of section .text:
 [ 	]+58:[ 	]+0ac59533[ 	]+clmul[ 	]+a0,a1,a2
 [ 	]+5c:[ 	]+0ac5b533[ 	]+clmulh[ 	]+a0,a1,a2
 [ 	]+60:[ 	]+0ac5a533[ 	]+clmulr[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48059513[ 	]+bclri[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f59513[ 	]+bclri[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+28059513[ 	]+bseti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f59513[ 	]+bseti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+68059513[ 	]+binvi[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f59513[ 	]+binvi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+4805d513[ 	]+bexti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f5d513[ 	]+bexti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+48c59533[ 	]+bclr[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+28c59533[ 	]+bset[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+68c59533[ 	]+binv[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5d533[ 	]+bext[ 	]+a0,a1,a2
diff --git a/gas/testsuite/gas/riscv/b-ext.s b/gas/testsuite/gas/riscv/b-ext.s
index 051dafd1719..a13a797f0dc 100644
--- a/gas/testsuite/gas/riscv/b-ext.s
+++ b/gas/testsuite/gas/riscv/b-ext.s
@@ -24,3 +24,15 @@  target:
 	clmul	a0, a1, a2
 	clmulh	a0, a1, a2
 	clmulr	a0, a1, a2
+	bclri   a0, a1, 0
+	bclri   a0, a1, 31
+	bseti   a0, a1, 0
+	bseti   a0, a1, 31
+	binvi   a0, a1, 0
+	binvi   a0, a1, 31
+	bexti   a0, a1, 0
+	bexti   a0, a1, 31
+	bclr    a0, a1, a2
+	bset    a0, a1, a2
+	binv    a0, a1, a2
+	bext    a0, a1, a2
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 9999da6241a..45a207da0cd 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -495,6 +495,22 @@ 
 #define MASK_CLMULH  0xfe00707f
 #define MATCH_CLMULR 0xa002033
 #define MASK_CLMULR  0xfe00707f
+#define MATCH_BCLRI 0x48001013
+#define MASK_BCLRI  0xfc00707f
+#define MATCH_BSETI 0x28001013
+#define MASK_BSETI  0xfc00707f
+#define MATCH_BINVI 0x68001013
+#define MASK_BINVI  0xfc00707f
+#define MATCH_BEXTI 0x48005013
+#define MASK_BEXTI  0xfc00707f
+#define MATCH_BCLR  0x48001033
+#define MASK_BCLR   0xfe00707f
+#define MATCH_BSET  0x28001033
+#define MASK_BSET   0xfe00707f
+#define MATCH_BINV  0x68001033
+#define MASK_BINV   0xfe00707f
+#define MATCH_BEXT  0x48005033
+#define MASK_BEXT   0xfe00707f
 #define MATCH_FLW 0x2007
 #define MASK_FLW  0x707f
 #define MATCH_FLD 0x3007
@@ -1102,6 +1118,14 @@  DECLARE_INSN(slli_uw, MATCH_SLLI_UW, MASK_SLLI_UW)
 DECLARE_INSN(clmul, MATCH_CLMUL, MASK_CLMUL)
 DECLARE_INSN(clmulh, MATCH_CLMULH, MASK_CLMULH)
 DECLARE_INSN(clmulr, MATCH_CLMULR, MASK_CLMULR)
+DECLARE_INSN(bclri, MATCH_BCLRI, MASK_BCLRI)
+DECLARE_INSN(bseti, MATCH_BSETI, MASK_BSETI)
+DECLARE_INSN(binvi, MATCH_BINVI, MASK_BINVI)
+DECLARE_INSN(bexti, MATCH_BEXTI, MASK_BEXTI)
+DECLARE_INSN(bclr, MATCH_BCLR, MASK_BCLR)
+DECLARE_INSN(bset, MATCH_BSET, MASK_BSET)
+DECLARE_INSN(binv, MATCH_BINV, MASK_BINV)
+DECLARE_INSN(bext, MATCH_BEXT, MASK_BEXT)
 DECLARE_INSN(flw, MATCH_FLW, MASK_FLW)
 DECLARE_INSN(fld, MATCH_FLD, MASK_FLD)
 DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index a8f47419f75..afcd41ff1dd 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -319,6 +319,7 @@  enum riscv_insn_class
   INSN_CLASS_ZBA,
   INSN_CLASS_ZBB,
   INSN_CLASS_ZBC,
+  INSN_CLASS_ZBS,
 };
 
 /* This structure holds information for a particular instruction.  */
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index e0621503b79..1a4c9f0e4fe 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -833,6 +833,15 @@  const struct riscv_opcode riscv_opcodes[] =
 {"clmulh",     0, INSN_CLASS_ZBC,  "d,s,t", MATCH_CLMULH, MASK_CLMULH, match_opcode, 0 },
 {"clmulr",     0, INSN_CLASS_ZBC,  "d,s,t", MATCH_CLMULR, MASK_CLMULR, match_opcode, 0 },
 
+/* Zbs instructions */
+{"bclri",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BCLRI, MASK_BCLRI, match_opcode, 0 },
+{"bseti",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BSETI, MASK_BSETI, match_opcode, 0 },
+{"binvi",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BINVI, MASK_BINVI, match_opcode, 0 },
+{"bexti",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BEXTI, MASK_BEXTI, match_opcode, 0 },
+{"bclr",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BCLR, MASK_BCLR, match_opcode, 0 },
+{"bset",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BSET, MASK_BSET, match_opcode, 0 },
+{"binv",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BINV, MASK_BINV, match_opcode, 0 },
+{"bext",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BEXT, MASK_BEXT, match_opcode, 0 },
 
 /* Terminate the list.  */
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}