public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/3] RISC-V: Add -menable-experimental-extensions and support bitmanip instructions
@ 2020-12-15 15:11 Nelson Chu
  2020-12-15 15:11 ` [PATCH 1/3] RISC-V: Support riscv " Nelson Chu
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Nelson Chu @ 2020-12-15 15:11 UTC (permalink / raw)
  To: binutils, claire, maxim.blinov, jimw, andrew, palmer, kito.cheng

Hi Guys,

The -menable-experimental-extensions option was originally discussed
in the following link,
https://sourceware.org/pipermail/binutils/2020-December/114439.html

And we already have riscv bitmanip support in the riscv github,
https://github.com/riscv/riscv-binutils-gdb/tree/riscv-binutils-2.35-rvb

The bitmanip implementations are basically based on the 0.92 spec, but
with the updates from tech-bitmanip mail list.  Eventually, these updates
should be merged back to the spec, and we probably need a new 0.93 version
or tag to make these changes stable.  However, the series of patches show
how the -menable-experimental-extensions option works, and it is the same
as what LLVM had done.  We are still the details of how this will work, so
any suggestion and feedback is welcome.

The tech-bitmanip mail list link,
https://lists.riscv.org/g/tech-bitmanip/topic/summary_of_current_proposals/77924315?p=,,,20,0,0,0::recentpostdate%2Fsticky,,,20,2,0,77924315

And here is the next steps of bitmanip ISA, which are arranged by Ken Dockser,
https://docs.google.com/spreadsheets/d/1toaPZS7L3k__ApHa6QufF36ESNzG9-_NkxSvF4lKuwc/edit#gid=0


BTW, the first patch is little bit difference compared to the
riscv-binutils-2.35-rvb branch.  Here are the difference,

* The spec said that (in Table 2.1) - B is all Zb* extensions except Zbr and
Zbt.  Therefore, I change the INSN_CLASS_B_OR_ZBR/ZBT to INSN_CLASS_ZBR/ZBT.

* I re-arranged the riscv-opcode table and collect ZB* together, to make the
table cleaner.

* rol[w] are ZBB in the tech-bitmanip, but they are ZBP in the 0.92 draft.

* zext.w is addu.w in the tech-bitmanip, but it is packw before.

However, we really need to update the bitmanip draft spec, according to the
tech-bitmanip mails and the table arranged by Ken Dockser, and also get a
new 0.93 version/tag to make the changes stable.


Thanks
Nelson


Hi Claire and Maxim,

I copy your commit name and mail from github, so if you prefer another ones,
please feel free to let me know.  Thank you very much :)

Nelson


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

* [PATCH 1/3] RISC-V: Support riscv bitmanip instructions.
  2020-12-15 15:11 [PATCH 0/3] RISC-V: Add -menable-experimental-extensions and support bitmanip instructions Nelson Chu
@ 2020-12-15 15:11 ` Nelson Chu
  2021-01-04 23:48   ` Jim Wilson
  2020-12-15 15:11 ` [PATCH 2/3] RISC-V: Define pseudo rev/orc/zip/unzip as alias instructions Nelson Chu
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Nelson Chu @ 2020-12-15 15:11 UTC (permalink / raw)
  To: binutils, claire, maxim.blinov, jimw, andrew, palmer, kito.cheng

From: Claire Xenia Wolf <claire@symbioticeda.com>

This patch is basically based on the github branch riscv-binutils-2.35-rvb,
which is in the riscv/riscv-binutils-gdb repo,
https://github.com/riscv/riscv-binutils-gdb/tree/riscv-binutils-2.35-rvb

2020-12-15  Claire Xenia Wolf  <claire@symbioticeda.com>
            Jim Wilson  <jimw@sifive.com>
            Maxim Blinov  <maxim.blinov@embecosm.com>
            Kito Cheng  <kito.cheng@sifive.com>

bfd/
    * elfxx-riscv.c (riscv_std_z_ext_strtab): Add b and zb* extensions.
gas/
    * config/tc-riscv.c (riscv_multi_subset_supports): Handle INSN_CLASS_B*.
    (riscv_get_default_ext_version): Do not check the default_isa_spec for
    draft extensions.
    (perm): New function.  Used to handle the bitmanip pseudos.
    (macro, macro_build): Handle bitmanip pseudos..
    (validate_riscv_insn): Add support for bitmanip instructions.
    (riscv_ip): Add new operand '|'.
    * testsuite/gas/riscv/attribute-draft-b.d: New testcases.
    * testsuite/gas/riscv/bitmanip-insns-32.d: Likewise.
    * testsuite/gas/riscv/bitmanip-insns-64.d: Likewise.
    * testsuite/gas/riscv/bitmanip-insns-pseudo-32.d: Likewise.
    * testsuite/gas/riscv/bitmanip-insns-pseudo-64.d: Likewise.
    * testsuite/gas/riscv/bitmanip-insns-pseudo.s: Likewise.
    * testsuite/gas/riscv/bitmanip-insns.s: Likewise.
include/
    * opcode/riscv-opc.h: Add bitmanip MASK/MATCH/DECLARE_INSN.
    * opcode/riscv.h: Add M_PERM to enum macro.
    (riscv_insn_class): Add INSN_CLASS_B*.
    (riscv_isa_spec_class): Add ISA_SPEC_CLASS_DRAFT.
opcodes/
    * riscv-dis.c (print_insn_args): Handle opernads '|' and 'r'.
    * riscv-opc.c (riscv_opcodes): Add bitmanip instructions.
---
 bfd/elfxx-riscv.c                                  |   4 +-
 gas/config/tc-riscv.c                              | 119 ++++++++-
 gas/testsuite/gas/riscv/attribute-draft-b.d        |   6 +
 gas/testsuite/gas/riscv/bitmanip-insns-32.d        |  97 +++++++
 gas/testsuite/gas/riscv/bitmanip-insns-64.d        | 177 +++++++++++++
 gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d |  61 +++++
 gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d |  84 ++++++
 gas/testsuite/gas/riscv/bitmanip-insns-pseudo.s    |  85 ++++++
 gas/testsuite/gas/riscv/bitmanip-insns.s           | 204 +++++++++++++++
 include/opcode/riscv-opc.h                         | 287 +++++++++++++++++++++
 include/opcode/riscv.h                             |  17 +-
 opcodes/riscv-dis.c                                |   7 +
 opcodes/riscv-opc.c                                | 224 +++++++++++++++-
 13 files changed, 1365 insertions(+), 7 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/attribute-draft-b.d
 create mode 100644 gas/testsuite/gas/riscv/bitmanip-insns-32.d
 create mode 100644 gas/testsuite/gas/riscv/bitmanip-insns-64.d
 create mode 100644 gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d
 create mode 100644 gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d
 create mode 100644 gas/testsuite/gas/riscv/bitmanip-insns-pseudo.s
 create mode 100644 gas/testsuite/gas/riscv/bitmanip-insns.s

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 35e46fa..016905d 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1597,7 +1597,9 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
 
 static const char * const riscv_std_z_ext_strtab[] =
 {
-  "zicsr", "zifencei", NULL
+  "zicsr", "zifencei",
+  "zba", "zbb", "zbc", "zbe", "zbf", "zbm", "zbp", "zbr", "zbs", "zbt",
+  NULL
 };
 
 static const char * const riscv_std_s_ext_strtab[] =
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index ca7e52a..ae3a8ad 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -251,6 +251,43 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class)
     case INSN_CLASS_ZIFENCEI:
       return riscv_subset_supports ("zifencei");
 
+    case INSN_CLASS_B_OR_ZBA:
+      return (riscv_subset_supports ("b")
+	      || riscv_subset_supports ("zba"));
+    case INSN_CLASS_B_OR_ZBB:
+      return (riscv_subset_supports ("b")
+	      || riscv_subset_supports ("zbb"));
+    case INSN_CLASS_B_OR_ZBC:
+      return (riscv_subset_supports ("b")
+	      || riscv_subset_supports ("zbc"));
+    case INSN_CLASS_B_OR_ZBE:
+      return (riscv_subset_supports ("b")
+	      || riscv_subset_supports ("zbe"));
+    case INSN_CLASS_B_OR_ZBF:
+      return (riscv_subset_supports ("b")
+	      || riscv_subset_supports ("zbf"));
+    case INSN_CLASS_B_OR_ZBM:
+      return (riscv_subset_supports ("b")
+	      || riscv_subset_supports ("zbm"));
+    case INSN_CLASS_B_OR_ZBP:
+      return (riscv_subset_supports ("b")
+	      || riscv_subset_supports ("zbp"));
+    case INSN_CLASS_ZBR:
+      return riscv_subset_supports ("zbr");
+    case INSN_CLASS_B_OR_ZBS:
+      return (riscv_subset_supports ("b")
+	      || riscv_subset_supports ("zbs"));
+    case INSN_CLASS_ZBT:
+      return riscv_subset_supports ("zbt");
+    case INSN_CLASS_B_OR_ZBB_OR_ZBP:
+      return (riscv_subset_supports ("b")
+	      || riscv_subset_supports ("zbb")
+	      || riscv_subset_supports ("zbp"));
+    case INSN_CLASS_B_OR_ZBF_OR_ZBP:
+      return (riscv_subset_supports ("b")
+	      || riscv_subset_supports ("zbf")
+	      || riscv_subset_supports ("zbp"));
+
     default:
       as_fatal ("Unreachable");
       return FALSE;
@@ -296,7 +333,8 @@ riscv_get_default_ext_version (const char *name,
 	 && ext->name
 	 && strcmp (ext->name, name) == 0)
     {
-      if (ext->isa_spec_class == default_isa_spec)
+      if (ext->isa_spec_class == ISA_SPEC_CLASS_DRAFT
+	  || ext->isa_spec_class == default_isa_spec)
 	{
 	  *major_version = ext->major_version;
 	  *minor_version = ext->minor_version;
@@ -970,6 +1008,7 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
       case '(': break;
       case ')': break;
       case '<': USE_BITS (OP_MASK_SHAMTW,	OP_SH_SHAMTW);	break;
+      case '|': USE_BITS (OP_MASK_SHAMTW,	OP_SH_SHAMTW);	break;
       case '>':	USE_BITS (OP_MASK_SHAMT,	OP_SH_SHAMT);	break;
       case 'A': break;
       case 'D':	USE_BITS (OP_MASK_RD,		OP_SH_RD);	break;
@@ -1249,6 +1288,15 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
 	  INSERT_OPERAND (RS2, insn, va_arg (args, int));
 	  continue;
 
+	case 'r':
+	  INSERT_OPERAND (RS3, insn, va_arg (args, int));
+	  continue;
+
+	case '<':
+	case '|':
+	  INSERT_OPERAND (SHAMTW, insn, va_arg (args, int));
+	  continue;
+
 	case '>':
 	  INSERT_OPERAND (SHAMT, insn, va_arg (args, int));
 	  continue;
@@ -1450,6 +1498,58 @@ riscv_ext (int destreg, int srcreg, unsigned shift, bfd_boolean sign)
     }
 }
 
+static void
+perm (int rd, int rs1, const char *op)
+{
+  const char *insn = NULL;
+  const char *p = op;
+  int shamt = 0;
+  int shfl = 0;
+
+  switch (p[0])
+    {
+    case 'r': insn = "grevi";   shamt = xlen-1;   p += 3; break;
+    case 'o': insn = "gorci";   shamt = xlen-1;   p += 3; break;
+    case 'z': insn = "shfli";   shamt = xlen/2-1; p += 3; shfl = 1; break;
+    case 'u': insn = "unshfli"; shamt = xlen/2-1; p += 5; shfl = 1; break;
+    default: as_fatal (_("internal error: bad permutation pseudo-instruction %s"), op);
+    }
+
+  switch (p[0])
+    {
+    case '2': shamt &= shamt << 1; p += 1; break;
+    case '4': shamt &= shamt << 2; p += 1; break;
+    case '8': shamt &= shamt << 3; p += 1; break;
+    case '1': shamt &= shamt << 4; p += 2; break;
+    case '3': shamt &= shamt << 5; p += 2;
+    }
+
+  if (p[0])
+    {
+      if (shfl)
+        switch (p[1])
+          {
+          case 'w': shamt &= 15; break;
+          case 'h': shamt &=  7; break;
+          case 'b': shamt &=  3; break;
+          case 'n': shamt &=  1; break;
+          default: as_fatal (_("internal error: bad permutation pseudo-instruction %s"), op);
+          }
+      else
+        switch (p[1])
+          {
+          case 'w': shamt &= 31; break;
+          case 'h': shamt &= 15; break;
+          case 'b': shamt &=  7; break;
+          case 'n': shamt &=  3; break;
+          case 'p': shamt &=  1; break;
+          default: as_fatal (_("internal error: bad permutation pseudo-instruction %s"), op);
+          }
+    }
+
+  macro_build (NULL, insn, "d,s,>", rd, rs1, shamt);
+}
+
 /* Expand RISC-V assembly macros into one or more instructions.  */
 static void
 macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
@@ -1458,6 +1558,8 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
   int rd = (ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD;
   int rs1 = (ip->insn_opcode >> OP_SH_RS1) & OP_MASK_RS1;
   int rs2 = (ip->insn_opcode >> OP_SH_RS2) & OP_MASK_RS2;
+  int rs3 = (ip->insn_opcode >> OP_SH_RS3) & OP_MASK_RS3;
+  int shamt = (ip->insn_opcode >> OP_SH_SHAMT) & OP_MASK_SHAMT;
   int mask = ip->insn_mo->mask;
 
   switch (mask)
@@ -1466,6 +1568,10 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
       load_const (rd, imm_expr);
       break;
 
+    case M_PERM:
+      perm (rd, rs1, ip->insn_mo->name);
+      break;
+
     case M_LA:
     case M_LLA:
       /* Load the address of a symbol into a register.  */
@@ -2265,6 +2371,17 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      s = expr_end;
 	      continue;
 
+	    case '|':		/* Shift amount, 0 - (XLEN/2-1).  */
+	      my_getExpression (imm_expr, s);
+	      check_absolute_expr (ip, imm_expr, FALSE);
+	      if ((unsigned long) imm_expr->X_add_number >= xlen/2)
+		as_bad (_("Improper shift amount (%lu)"),
+			(unsigned long) imm_expr->X_add_number);
+	      INSERT_OPERAND (SHAMTW, *ip, imm_expr->X_add_number);
+	      imm_expr->X_op = O_absent;
+	      s = expr_end;
+	      continue;
+
 	    case '>':		/* Shift amount, 0 - (XLEN-1).  */
 	      my_getExpression (imm_expr, s);
 	      check_absolute_expr (ip, imm_expr, FALSE);
diff --git a/gas/testsuite/gas/riscv/attribute-draft-b.d b/gas/testsuite/gas/riscv/attribute-draft-b.d
new file mode 100644
index 0000000..0af5b71
--- /dev/null
+++ b/gas/testsuite/gas/riscv/attribute-draft-b.d
@@ -0,0 +1,6 @@
+#as: -march-attr -march=rv32ib_zba_zbb_zbc_zbe_zbf_zbm_zbp_zbr_zbs_zbt
+#readelf: -A
+#source: empty.s
+Attribute Section: riscv
+File Attributes
+  Tag_RISCV_arch: .*b0p92_zba0p92_zbb0p92_zbc0p92_zbe0p92_zbf0p92_zbm0p92_zbp0p92_zbr0p92_zbs0p92_zbt0p92.*
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-32.d b/gas/testsuite/gas/riscv/bitmanip-insns-32.d
new file mode 100644
index 0000000..df691cc
--- /dev/null
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-32.d
@@ -0,0 +1,97 @@
+#as: -march=rv32ib_zbr_zbt
+#source: bitmanip-insns.s
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ 	]+[0-9a-f]+:[ 	]+20c5a533[ 	]+sh1add[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+20c5c533[ 	]+sh2add[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+20c5e533[ 	]+sh3add[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+60059513[ 	]+clz[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+60159513[ 	]+ctz[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+60259513[ 	]+pcnt[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0ac5c533[ 	]+min[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0ac5e533[ 	]+max[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0ac5d533[ 	]+minu[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0ac5f533[ 	]+maxu[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+60459513[ 	]+sext.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+60559513[ 	]+sext.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+40c5f533[ 	]+andn[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+40c5e533[ 	]+orn[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+00c5c533[ 	]+xor[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+6005d513[ 	]+rori[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+61f5d513[ 	]+rori[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+60c5d533[ 	]+ror[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+6005d513[ 	]+rori[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+61f5d513[ 	]+rori[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+60c59533[ 	]+rol[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+2805d513[ 	]+gorci[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f5d513[ 	]+gorci[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+28c5d533[ 	]+gorc[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+2805d513[ 	]+gorci[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f5d513[ 	]+gorci[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+6805d513[ 	]+grevi[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f5d513[ 	]+grevi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+68c5d533[ 	]+grev[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+6805d513[ 	]+grevi[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f5d513[ 	]+grevi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+08059513[ 	]+shfli[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+08f59513[ 	]+shfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+08c59533[ 	]+shfl[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+08059513[ 	]+shfli[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+08f59513[ 	]+shfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+0805d513[ 	]+unshfli[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+08f5d513[ 	]+unshfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+08c5d533[ 	]+unshfl[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0805d513[ 	]+unshfli[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+08f5d513[ 	]+unshfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+08c5c533[ 	]+pack[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5c533[ 	]+packu[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+08c5f533[ 	]+packh[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+28c5a533[ 	]+xperm.n[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+28c5c533[ 	]+xperm.b[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+28c5b533[ 	]+xperm.h[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5f533[ 	]+bfp[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0ac59533[ 	]+clmul[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0ac5b533[ 	]+clmulh[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0ac5a533[ 	]+clmulr[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5e533[ 	]+bdep[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+08c5e533[ 	]+bext[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+61059513[ 	]+crc32.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+61159513[ 	]+crc32.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+61259513[ 	]+crc32.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+61859513[ 	]+crc32c.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+61959513[ 	]+crc32c.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+61a59513[ 	]+crc32c.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+48059513[ 	]+sbclri[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f59513[ 	]+sbclri[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+48c59533[ 	]+sbclr[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48059513[ 	]+sbclri[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f59513[ 	]+sbclri[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+28059513[ 	]+sbseti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f59513[ 	]+sbseti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+28c59533[ 	]+sbset[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+28059513[ 	]+sbseti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f59513[ 	]+sbseti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+68059513[ 	]+sbinvi[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f59513[ 	]+sbinvi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+68c59533[ 	]+sbinv[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+68059513[ 	]+sbinvi[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f59513[ 	]+sbinvi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+4805d513[ 	]+sbexti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f5d513[ 	]+sbexti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+48c5d533[ 	]+sbext[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+4805d513[ 	]+sbexti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f5d513[ 	]+sbexti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+6eb61533[ 	]+cmix[ 	]+a0,a1,a2,a3
+[ 	]+[0-9a-f]+:[ 	]+6eb65533[ 	]+cmov[ 	]+a0,a1,a2,a3
+[ 	]+[0-9a-f]+:[ 	]+6405d513[ 	]+fsri[ 	]+a0,a1,a2,0x0
+[ 	]+[0-9a-f]+:[ 	]+65f5d513[ 	]+fsri[ 	]+a0,a1,a2,0x1f
+[ 	]+[0-9a-f]+:[ 	]+64d5d533[ 	]+fsr[ 	]+a0,a1,a2,a3
+[ 	]+[0-9a-f]+:[ 	]+6405d513[ 	]+fsri[ 	]+a0,a1,a2,0x0
+[ 	]+[0-9a-f]+:[ 	]+65f5d513[ 	]+fsri[ 	]+a0,a1,a2,0x1f
+[ 	]+[0-9a-f]+:[ 	]+64d59533[ 	]+fsl[ 	]+a0,a1,a2,a3
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-64.d b/gas/testsuite/gas/riscv/bitmanip-insns-64.d
new file mode 100644
index 0000000..e4cf67c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-64.d
@@ -0,0 +1,177 @@
+#as: -march=rv64ib_zbr_zbt -defsym __64_bit__=1
+#source: bitmanip-insns.s
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ 	]+[0-9a-f]+:[ 	]+20c5a533[ 	]+sh1add[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+20c5c533[ 	]+sh2add[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+20c5e533[ 	]+sh3add[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0805951b[ 	]+slliu.w[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+0bf5951b[ 	]+slliu.w[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+08c5853b[ 	]+addu.w[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+20c5a53b[ 	]+sh1addu.w[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+20c5c53b[ 	]+sh2addu.w[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+20c5e53b[ 	]+sh3addu.w[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+60059513[ 	]+clz[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+60159513[ 	]+ctz[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+60259513[ 	]+pcnt[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0ac5c533[ 	]+min[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0ac5e533[ 	]+max[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0ac5d533[ 	]+minu[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0ac5f533[ 	]+maxu[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+60459513[ 	]+sext.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+60559513[ 	]+sext.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+40c5f533[ 	]+andn[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+40c5e533[ 	]+orn[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+00c5c533[ 	]+xor[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+6005d513[ 	]+rori[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+61f5d513[ 	]+rori[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+60c5d533[ 	]+ror[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+6005d513[ 	]+rori[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+61f5d513[ 	]+rori[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+60c59533[ 	]+rol[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+6005951b[ 	]+clzw[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6015951b[ 	]+ctzw[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6025951b[ 	]+pcntw[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+63f5d513[ 	]+rori[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+63f5d513[ 	]+rori[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+6005d51b[ 	]+roriw[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+61f5d51b[ 	]+roriw[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+60c5d53b[ 	]+rorw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+6005d51b[ 	]+roriw[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+61f5d51b[ 	]+roriw[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+60c5953b[ 	]+rolw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+2805d513[ 	]+gorci[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f5d513[ 	]+gorci[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+28c5d533[ 	]+gorc[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+2805d513[ 	]+gorci[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f5d513[ 	]+gorci[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+6805d513[ 	]+grevi[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f5d513[ 	]+grevi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+68c5d533[ 	]+grev[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+6805d513[ 	]+grevi[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f5d513[ 	]+grevi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+08059513[ 	]+shfli[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+08f59513[ 	]+shfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+08c59533[ 	]+shfl[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+08059513[ 	]+shfli[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+08f59513[ 	]+shfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+0805d513[ 	]+unshfli[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+08f5d513[ 	]+unshfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+08c5d533[ 	]+unshfl[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0805d513[ 	]+unshfli[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+08f5d513[ 	]+unshfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+08c5c533[ 	]+pack[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5c533[ 	]+packu[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+08c5f533[ 	]+packh[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+28c5a533[ 	]+xperm.n[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+28c5c533[ 	]+xperm.b[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+28c5b533[ 	]+xperm.h[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+2bf5d513[ 	]+gorci[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+2bf5d513[ 	]+gorci[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+6bf5d513[ 	]+grevi[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+6bf5d513[ 	]+grevi[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+09f59513[ 	]+shfli[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+09f59513[ 	]+shfli[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+09f5d513[ 	]+unshfli[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+09f5d513[ 	]+unshfli[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+2805d51b[ 	]+gorciw[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f5d51b[ 	]+gorciw[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+28c5d53b[ 	]+gorcw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+2805d51b[ 	]+gorciw[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f5d51b[ 	]+gorciw[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+6805d51b[ 	]+greviw[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f5d51b[ 	]+greviw[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+68c5d53b[ 	]+grevw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+6805d51b[ 	]+greviw[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f5d51b[ 	]+greviw[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+08c5953b[ 	]+shflw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+08c5d53b[ 	]+unshflw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+08c5c53b[ 	]+packw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5c53b[ 	]+packuw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+28c58533[ 	]+xperm.w[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5f533[ 	]+bfp[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5f53b[ 	]+bfpw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0ac59533[ 	]+clmul[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0ac5b533[ 	]+clmulh[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+0ac5a533[ 	]+clmulr[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5e533[ 	]+bdep[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+08c5e533[ 	]+bext[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5e53b[ 	]+bdepw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+08c5e53b[ 	]+bextw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+60359513[ 	]+bmatflip[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08c5b533[ 	]+bmator[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5b533[ 	]+bmatxor[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+61059513[ 	]+crc32.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+61159513[ 	]+crc32.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+61259513[ 	]+crc32.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+61859513[ 	]+crc32c.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+61959513[ 	]+crc32c.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+61a59513[ 	]+crc32c.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+61359513[ 	]+crc32.d[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+61b59513[ 	]+crc32c.d[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+48059513[ 	]+sbclri[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f59513[ 	]+sbclri[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+48c59533[ 	]+sbclr[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48059513[ 	]+sbclri[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f59513[ 	]+sbclri[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+28059513[ 	]+sbseti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f59513[ 	]+sbseti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+28c59533[ 	]+sbset[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+28059513[ 	]+sbseti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f59513[ 	]+sbseti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+68059513[ 	]+sbinvi[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f59513[ 	]+sbinvi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+68c59533[ 	]+sbinv[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+68059513[ 	]+sbinvi[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f59513[ 	]+sbinvi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+4805d513[ 	]+sbexti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f5d513[ 	]+sbexti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+48c5d533[ 	]+sbext[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+4805d513[ 	]+sbexti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f5d513[ 	]+sbexti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+4bf59513[ 	]+sbclri[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+4bf59513[ 	]+sbclri[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+2bf59513[ 	]+sbseti[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+2bf59513[ 	]+sbseti[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+6bf59513[ 	]+sbinvi[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+6bf59513[ 	]+sbinvi[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+4bf5d513[ 	]+sbexti[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+4bf5d513[ 	]+sbexti[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+4805951b[ 	]+sbclriw[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f5951b[ 	]+sbclriw[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+48c5953b[ 	]+sbclrw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+4805951b[ 	]+sbclriw[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f5951b[ 	]+sbclriw[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+2805951b[ 	]+sbsetiw[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f5951b[ 	]+sbsetiw[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+28c5953b[ 	]+sbsetw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+2805951b[ 	]+sbsetiw[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f5951b[ 	]+sbsetiw[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+6805951b[ 	]+sbinviw[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f5951b[ 	]+sbinviw[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+68c5953b[ 	]+sbinvw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+6805951b[ 	]+sbinviw[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f5951b[ 	]+sbinviw[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+48c5d53b[ 	]+sbextw[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+6eb61533[ 	]+cmix[ 	]+a0,a1,a2,a3
+[ 	]+[0-9a-f]+:[ 	]+6eb65533[ 	]+cmov[ 	]+a0,a1,a2,a3
+[ 	]+[0-9a-f]+:[ 	]+6405d513[ 	]+fsri[ 	]+a0,a1,a2,0x0
+[ 	]+[0-9a-f]+:[ 	]+65f5d513[ 	]+fsri[ 	]+a0,a1,a2,0x1f
+[ 	]+[0-9a-f]+:[ 	]+64d5d533[ 	]+fsr[ 	]+a0,a1,a2,a3
+[ 	]+[0-9a-f]+:[ 	]+6405d513[ 	]+fsri[ 	]+a0,a1,a2,0x0
+[ 	]+[0-9a-f]+:[ 	]+65f5d513[ 	]+fsri[ 	]+a0,a1,a2,0x1f
+[ 	]+[0-9a-f]+:[ 	]+64d59533[ 	]+fsl[ 	]+a0,a1,a2,a3
+[ 	]+[0-9a-f]+:[ 	]+67f5d513[ 	]+fsri[ 	]+a0,a1,a2,0x3f
+[ 	]+[0-9a-f]+:[ 	]+67f5d513[ 	]+fsri[ 	]+a0,a1,a2,0x3f
+[ 	]+[0-9a-f]+:[ 	]+6405d51b[ 	]+fsriw[ 	]+a0,a1,a2,0x0
+[ 	]+[0-9a-f]+:[ 	]+65f5d51b[ 	]+fsriw[ 	]+a0,a1,a2,0x1f
+[ 	]+[0-9a-f]+:[ 	]+64d5d53b[ 	]+fsrw[ 	]+a0,a1,a2,a3
+[ 	]+[0-9a-f]+:[ 	]+6405d51b[ 	]+fsriw[ 	]+a0,a1,a2,0x0
+[ 	]+[0-9a-f]+:[ 	]+65f5d51b[ 	]+fsriw[ 	]+a0,a1,a2,0x1f
+[ 	]+[0-9a-f]+:[ 	]+64d5953b[ 	]+fslw[ 	]+a0,a1,a2,a3
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d
new file mode 100644
index 0000000..f9e7b8b
--- /dev/null
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d
@@ -0,0 +1,61 @@
+#as: -march=rv32ib
+#source: bitmanip-insns-pseudo.s
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ 	]+[0-9a-f]+:[ 	]+0805c533[ 	]+zext.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6815d513[ 	]+grevi[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+6825d513[ 	]+grevi[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+6835d513[ 	]+grevi[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+6845d513[ 	]+grevi[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+6865d513[ 	]+grevi[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+6875d513[ 	]+grevi[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+6885d513[ 	]+grevi[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+68c5d513[ 	]+grevi[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+68e5d513[ 	]+grevi[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+68f5d513[ 	]+grevi[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+6905d513[ 	]+grevi[ 	]+a0,a1,0x10
+[ 	]+[0-9a-f]+:[ 	]+6985d513[ 	]+grevi[ 	]+a0,a1,0x18
+[ 	]+[0-9a-f]+:[ 	]+69c5d513[ 	]+grevi[ 	]+a0,a1,0x1c
+[ 	]+[0-9a-f]+:[ 	]+69e5d513[ 	]+grevi[ 	]+a0,a1,0x1e
+[ 	]+[0-9a-f]+:[ 	]+69f5d513[ 	]+grevi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+2815d513[ 	]+gorci[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+2825d513[ 	]+gorci[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+2835d513[ 	]+gorci[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+2845d513[ 	]+gorci[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+2865d513[ 	]+gorci[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+2875d513[ 	]+gorci[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+2885d513[ 	]+gorci[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+28c5d513[ 	]+gorci[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+28e5d513[ 	]+gorci[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+28f5d513[ 	]+gorci[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+2905d513[ 	]+gorci[ 	]+a0,a1,0x10
+[ 	]+[0-9a-f]+:[ 	]+2985d513[ 	]+gorci[ 	]+a0,a1,0x18
+[ 	]+[0-9a-f]+:[ 	]+29c5d513[ 	]+gorci[ 	]+a0,a1,0x1c
+[ 	]+[0-9a-f]+:[ 	]+29e5d513[ 	]+gorci[ 	]+a0,a1,0x1e
+[ 	]+[0-9a-f]+:[ 	]+29f5d513[ 	]+gorci[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+08159513[ 	]+shfli[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+08259513[ 	]+shfli[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+08359513[ 	]+shfli[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+08459513[ 	]+shfli[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+08659513[ 	]+shfli[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+08759513[ 	]+shfli[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+08859513[ 	]+shfli[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+08c59513[ 	]+shfli[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+08e59513[ 	]+shfli[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+08f59513[ 	]+shfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+0815d513[ 	]+unshfli[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+0825d513[ 	]+unshfli[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+0835d513[ 	]+unshfli[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+0845d513[ 	]+unshfli[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+0865d513[ 	]+unshfli[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+0875d513[ 	]+unshfli[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+0885d513[ 	]+unshfli[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+08c5d513[ 	]+unshfli[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+08e5d513[ 	]+unshfli[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+08f5d513[ 	]+unshfli[ 	]+a0,a1,0xf
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d
new file mode 100644
index 0000000..0c25bae
--- /dev/null
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d
@@ -0,0 +1,84 @@
+#as: -march=rv64ib -defsym __64_bit__=1
+#source: bitmanip-insns-pseudo.s
+#objdump: -dr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ 	]+[0-9a-f]+:[ 	]+0805c53b[ 	]+zext.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6815d513[ 	]+grevi[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+6825d513[ 	]+grevi[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+6835d513[ 	]+grevi[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+6845d513[ 	]+grevi[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+6865d513[ 	]+grevi[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+6875d513[ 	]+grevi[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+6885d513[ 	]+grevi[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+68c5d513[ 	]+grevi[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+68e5d513[ 	]+grevi[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+68f5d513[ 	]+grevi[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+6b05d513[ 	]+grevi[ 	]+a0,a1,0x30
+[ 	]+[0-9a-f]+:[ 	]+6b85d513[ 	]+grevi[ 	]+a0,a1,0x38
+[ 	]+[0-9a-f]+:[ 	]+6bc5d513[ 	]+grevi[ 	]+a0,a1,0x3c
+[ 	]+[0-9a-f]+:[ 	]+6be5d513[ 	]+grevi[ 	]+a0,a1,0x3e
+[ 	]+[0-9a-f]+:[ 	]+6bf5d513[ 	]+grevi[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+2815d513[ 	]+gorci[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+2825d513[ 	]+gorci[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+2835d513[ 	]+gorci[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+2845d513[ 	]+gorci[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+2865d513[ 	]+gorci[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+2875d513[ 	]+gorci[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+2885d513[ 	]+gorci[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+28c5d513[ 	]+gorci[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+28e5d513[ 	]+gorci[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+28f5d513[ 	]+gorci[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+2b05d513[ 	]+gorci[ 	]+a0,a1,0x30
+[ 	]+[0-9a-f]+:[ 	]+2b85d513[ 	]+gorci[ 	]+a0,a1,0x38
+[ 	]+[0-9a-f]+:[ 	]+2bc5d513[ 	]+gorci[ 	]+a0,a1,0x3c
+[ 	]+[0-9a-f]+:[ 	]+2be5d513[ 	]+gorci[ 	]+a0,a1,0x3e
+[ 	]+[0-9a-f]+:[ 	]+2bf5d513[ 	]+gorci[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+08159513[ 	]+shfli[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+08259513[ 	]+shfli[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+08359513[ 	]+shfli[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+08459513[ 	]+shfli[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+08659513[ 	]+shfli[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+08759513[ 	]+shfli[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+09859513[ 	]+shfli[ 	]+a0,a1,0x18
+[ 	]+[0-9a-f]+:[ 	]+09c59513[ 	]+shfli[ 	]+a0,a1,0x1c
+[ 	]+[0-9a-f]+:[ 	]+09e59513[ 	]+shfli[ 	]+a0,a1,0x1e
+[ 	]+[0-9a-f]+:[ 	]+09f59513[ 	]+shfli[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+0815d513[ 	]+unshfli[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+0825d513[ 	]+unshfli[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+0835d513[ 	]+unshfli[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+0845d513[ 	]+unshfli[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+0865d513[ 	]+unshfli[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+0875d513[ 	]+unshfli[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+0985d513[ 	]+unshfli[ 	]+a0,a1,0x18
+[ 	]+[0-9a-f]+:[ 	]+09c5d513[ 	]+unshfli[ 	]+a0,a1,0x1c
+[ 	]+[0-9a-f]+:[ 	]+09e5d513[ 	]+unshfli[ 	]+a0,a1,0x1e
+[ 	]+[0-9a-f]+:[ 	]+09f5d513[ 	]+unshfli[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+0805853b[ 	]+zext.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6905d513[ 	]+grevi[ 	]+a0,a1,0x10
+[ 	]+[0-9a-f]+:[ 	]+6985d513[ 	]+grevi[ 	]+a0,a1,0x18
+[ 	]+[0-9a-f]+:[ 	]+69c5d513[ 	]+grevi[ 	]+a0,a1,0x1c
+[ 	]+[0-9a-f]+:[ 	]+69e5d513[ 	]+grevi[ 	]+a0,a1,0x1e
+[ 	]+[0-9a-f]+:[ 	]+69f5d513[ 	]+grevi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+6a05d513[ 	]+grevi[ 	]+a0,a1,0x20
+[ 	]+[0-9a-f]+:[ 	]+2905d513[ 	]+gorci[ 	]+a0,a1,0x10
+[ 	]+[0-9a-f]+:[ 	]+2985d513[ 	]+gorci[ 	]+a0,a1,0x18
+[ 	]+[0-9a-f]+:[ 	]+29c5d513[ 	]+gorci[ 	]+a0,a1,0x1c
+[ 	]+[0-9a-f]+:[ 	]+29e5d513[ 	]+gorci[ 	]+a0,a1,0x1e
+[ 	]+[0-9a-f]+:[ 	]+29f5d513[ 	]+gorci[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+2a05d513[ 	]+gorci[ 	]+a0,a1,0x20
+[ 	]+[0-9a-f]+:[ 	]+08859513[ 	]+shfli[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+08c59513[ 	]+shfli[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+08e59513[ 	]+shfli[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+08f59513[ 	]+shfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+09059513[ 	]+shfli[ 	]+a0,a1,0x10
+[ 	]+[0-9a-f]+:[ 	]+0885d513[ 	]+unshfli[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+08c5d513[ 	]+unshfli[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+08e5d513[ 	]+unshfli[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+08f5d513[ 	]+unshfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+0905d513[ 	]+unshfli[ 	]+a0,a1,0x10
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo.s b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo.s
new file mode 100644
index 0000000..4c38e0a2
--- /dev/null
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo.s
@@ -0,0 +1,85 @@
+	zext.h  a0, a1	/* ZBB  */
+
+	rev.p	a0, a1
+	rev2.n	a0, a1
+	rev.n	a0, a1
+	rev4.b	a0, a1
+	rev2.b	a0, a1
+	rev.b	a0, a1
+	rev8.h	a0, a1
+	rev4.h	a0, a1
+	rev2.h	a0, a1
+	rev.h	a0, a1
+	rev16	a0, a1
+	rev8	a0, a1	/* ZBB  */
+	rev4	a0, a1
+	rev2	a0, a1
+	rev	a0, a1
+
+	orc.p	a0, a1
+	orc2.n	a0, a1
+	orc.n	a0, a1
+	orc4.b	a0, a1
+	orc2.b	a0, a1
+	orc.b	a0, a1	/* ZBB  */
+	orc8.h	a0, a1
+	orc4.h	a0, a1
+	orc2.h	a0, a1
+	orc.h	a0, a1
+	orc16	a0, a1
+	orc8	a0, a1
+	orc4	a0, a1
+	orc2	a0, a1
+	orc	a0, a1
+
+	zip.n	a0, a1
+	zip2.b	a0, a1
+	zip.b	a0, a1
+	zip4.h	a0, a1
+	zip2.h	a0, a1
+	zip.h	a0, a1
+	zip8	a0, a1
+	zip4	a0, a1
+	zip2	a0, a1
+	zip	a0, a1
+
+	unzip.n		a0, a1
+	unzip2.b	a0, a1
+	unzip.b		a0, a1
+	unzip4.h	a0, a1
+	unzip2.h	a0, a1
+	unzip.h		a0, a1
+	unzip8		a0, a1
+	unzip4		a0, a1
+	unzip2		a0, a1
+	unzip		a0, a1
+
+.ifdef __64_bit__
+	zext.w  a0, a1	/* ZBB  */
+
+	rev16.w	a0, a1
+	rev8.w	a0, a1
+	rev4.w	a0, a1
+	rev2.w	a0, a1
+	rev.w	a0, a1
+	rev32	a0, a1
+
+	orc16.w	a0, a1
+	orc8.w	a0, a1
+	orc4.w	a0, a1
+	orc2.w	a0, a1
+	orc.w	a0, a1
+	orc32	a0, a1
+
+	zip8.w	a0, a1
+	zip4.w	a0, a1
+	zip2.w	a0, a1
+	zip.w	a0, a1
+	zip16	a0, a1
+
+	unzip8.w	a0, a1
+	unzip4.w	a0, a1
+	unzip2.w	a0, a1
+	unzip.w		a0, a1
+	unzip16		a0, a1
+.endif
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns.s b/gas/testsuite/gas/riscv/bitmanip-insns.s
new file mode 100644
index 0000000..f39faeb
--- /dev/null
+++ b/gas/testsuite/gas/riscv/bitmanip-insns.s
@@ -0,0 +1,204 @@
+	# ZBA
+	sh1add	a0, a1, a2
+	sh2add	a0, a1, a2
+	sh3add	a0, a1, a2
+.ifdef __64_bit__
+	slliu.w		a0, a1, 0
+	slliu.w		a0, a1, 63
+	addu.w		a0, a1, a2
+	sh1addu.w	a0, a1, a2
+	sh2addu.w	a0, a1, a2
+	sh3addu.w	a0, a1, a2
+.endif
+
+	# ZBB
+	clz	a0, a1
+	ctz	a0, a1
+	pcnt	a0, a1
+	min	a0, a1, a2
+	max	a0, a1, a2
+	minu	a0, a1, a2
+	maxu	a0, a1, a2
+	sext.b	a0, a1
+	sext.h	a0, a1
+	andn	a0, a1, a2	/* ZBB or ZBP  */
+	orn	a0, a1, a2	/* ZBB or ZBP  */
+	xor	a0, a1, a2	/* ZBB or ZBP  */
+	rori	a0, a1, 0	/* ZBB or ZBP  */
+	rori	a0, a1, 31	/* ZBB or ZBP  */
+	ror	a0, a1, a2	/* ZBB or ZBP  */
+	ror	a0, a1, 0	/* ZBB or ZBP  */
+	ror	a0, a1, 31	/* ZBB or ZBP  */
+	rol	a0, a1, a2	/* ZBB or ZBP  */
+.ifdef __64_bit__
+	clzw	a0, a1
+	ctzw	a0, a1
+	pcntw	a0, a1
+	rori	a0, a1, 63	/* ZBB or ZBP  */
+	ror	a0, a1, 63	/* ZBB or ZBP  */
+	roriw	a0, a1, 0	/* ZBB or ZBP  */
+	roriw	a0, a1, 31	/* ZBB or ZBP  */
+	rorw	a0, a1, a2	/* ZBB or ZBP  */
+	rorw	a0, a1, 0	/* ZBB or ZBP  */
+	rorw	a0, a1, 31	/* ZBB or ZBP  */
+	rolw	a0, a1, a2	/* ZBB or ZBP  */
+.endif
+
+	# ZBP
+	gorci	a0, a1, 0
+	gorci	a0, a1, 31
+	gorc	a0, a1, a2
+	gorc	a0, a1, 0
+	gorc	a0, a1, 31
+	grevi	a0, a1, 0
+	grevi	a0, a1, 31
+	grev	a0, a1, a2
+	grev	a0, a1, 0
+	grev	a0, a1, 31
+	shfli	a0, a1, 0
+	shfli	a0, a1, 15
+	shfl	a0, a1, a2
+	shfl	a0, a1, 0
+	shfl	a0, a1, 15
+	unshfli	a0, a1, 0
+	unshfli	a0, a1, 15
+	unshfl	a0, a1, a2
+	unshfl	a0, a1, 0
+	unshfl	a0, a1, 15
+	pack	a0, a1, a2	/* ZBF or ZBP  */
+	packu	a0, a1, a2
+	packh	a0, a1, a2	/* ZBF or ZBP  */
+	xperm.n	a0, a1, a2
+	xperm.b	a0, a1, a2
+	xperm.h	a0, a1, a2
+.ifdef __64_bit__
+	gorci	a0, a1, 63
+	gorc	a0, a1, 63
+	grevi	a0, a1, 63
+	grev	a0, a1, 63
+	shfli	a0, a1, 31
+	shfl	a0, a1, 31
+	unshfli	a0, a1, 31
+	unshfl	a0, a1, 31
+	gorciw	a0, a1, 0
+	gorciw	a0, a1, 31
+	gorcw	a0, a1, a2
+	gorcw	a0, a1, 0
+	gorcw	a0, a1, 31
+	greviw	a0, a1, 0
+	greviw	a0, a1, 31
+	grevw	a0, a1, a2
+	grevw	a0, a1, 0
+	grevw	a0, a1, 31
+	shflw	a0, a1, a2
+	unshflw	a0, a1, a2
+	packw	a0, a1, a2	/* ZBF or ZBP  */
+	packuw	a0, a1, a2
+	xperm.w	a0, a1, a2
+.endif
+
+	# ZBF
+	bfp	a0, a1, a2
+.ifdef __64_bit__
+	bfpw	a0, a1, a2
+.endif
+
+	# ZBC
+	clmul	a0, a1, a2
+	clmulh	a0, a1, a2
+	clmulr	a0, a1, a2
+
+	# ZBE
+	bdep	a0, a1, a2
+	bext	a0, a1, a2
+.ifdef __64_bit__
+	bdepw	a0, a1, a2
+	bextw	a0, a1, a2
+.endif
+
+	# ZBM
+.ifdef __64_bit__
+	bmatflip a0, a1
+	bmator	a0, a1, a2
+	bmatxor	a0, a1, a2
+.endif
+
+	# ZBR
+	crc32.b		a0, a1
+	crc32.h		a0, a1
+	crc32.w		a0, a1
+	crc32c.b	a0, a1
+	crc32c.h	a0, a1
+	crc32c.w	a0, a1
+.ifdef __64_bit__
+	crc32.d		a0, a1
+	crc32c.d	a0, a1
+.endif
+
+	# ZBS
+	sbclri	a0, a1, 0
+	sbclri	a0, a1, 31
+	sbclr	a0, a1, a2
+	sbclr	a0, a1, 0
+	sbclr	a0, a1, 31
+	sbseti	a0, a1, 0
+	sbseti	a0, a1, 31
+	sbset	a0, a1, a2
+	sbset	a0, a1, 0
+	sbset	a0, a1, 31
+	sbinvi	a0, a1, 0
+	sbinvi	a0, a1, 31
+	sbinv	a0, a1, a2
+	sbinv	a0, a1, 0
+	sbinv	a0, a1, 31
+	sbexti	a0, a1, 0
+	sbexti	a0, a1, 31
+	sbext	a0, a1, a2
+	sbext	a0, a1, 0
+	sbext	a0, a1, 31
+.ifdef __64_bit__
+	sbclri	a0, a1, 63
+	sbclr	a0, a1, 63
+	sbseti	a0, a1, 63
+	sbset	a0, a1, 63
+	sbinvi	a0, a1, 63
+	sbinv	a0, a1, 63
+	sbexti	a0, a1, 63
+	sbext	a0, a1, 63
+	sbclriw	a0, a1, 0
+	sbclriw	a0, a1, 31
+	sbclrw	a0, a1, a2
+	sbclrw	a0, a1, 0
+	sbclrw	a0, a1, 31
+	sbsetiw	a0, a1, 0
+	sbsetiw	a0, a1, 31
+	sbsetw	a0, a1, a2
+	sbsetw	a0, a1, 0
+	sbsetw	a0, a1, 31
+	sbinviw	a0, a1, 0
+	sbinviw	a0, a1, 31
+	sbinvw	a0, a1, a2
+	sbinvw	a0, a1, 0
+	sbinvw	a0, a1, 31
+	sbextw	a0, a1, a2
+.endif
+
+	# ZBT
+	cmix	a0, a1, a2, a3
+	cmov	a0, a1, a2, a3
+	fsri	a0, a1, a2, 0
+	fsri	a0, a1, a2, 31
+	fsr	a0, a1, a2, a3
+	fsr	a0, a1, a2, 0
+	fsr	a0, a1, a2, 31
+	fsl	a0, a1, a2, a3
+.ifdef __64_bit__
+	fsri	a0, a1, a2, 63
+	fsr	a0, a1, a2, 63
+	fsriw	a0, a1, a2, 0
+	fsriw	a0, a1, a2, 31
+	fsrw	a0, a1, a2, a3
+	fsrw	a0, a1, a2, 0
+	fsrw	a0, a1, a2, 31
+	fslw	a0, a1, a2, a3
+.endif
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 158de32..e53b986 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -189,6 +189,197 @@
 #define MASK_REMW  0xfe00707f
 #define MATCH_REMUW 0x200703b
 #define MASK_REMUW  0xfe00707f
+#define MATCH_ANDN 0x40007033
+#define MASK_ANDN  0xfe00707f
+#define MATCH_ORN 0x40006033
+#define MASK_ORN  0xfe00707f
+#define MATCH_XNOR 0x40004033
+#define MASK_XNOR  0xfe00707f
+#define MATCH_ROL 0x60001033
+#define MASK_ROL  0xfe00707f
+#define MATCH_ROR 0x60005033
+#define MASK_ROR  0xfe00707f
+#define MATCH_SBCLR 0x48001033
+#define MASK_SBCLR  0xfe00707f
+#define MATCH_SBSET 0x28001033
+#define MASK_SBSET  0xfe00707f
+#define MATCH_SBINV 0x68001033
+#define MASK_SBINV  0xfe00707f
+#define MATCH_SBEXT 0x48005033
+#define MASK_SBEXT  0xfe00707f
+#define MATCH_GORC 0x28005033
+#define MASK_GORC  0xfe00707f
+#define MATCH_GREV 0x68005033
+#define MASK_GREV  0xfe00707f
+#define MATCH_RORI 0x60005013
+#define MASK_RORI  0xfc00707f
+#define MATCH_SBCLRI 0x48001013
+#define MASK_SBCLRI  0xfc00707f
+#define MATCH_SBSETI 0x28001013
+#define MASK_SBSETI  0xfc00707f
+#define MATCH_SBINVI 0x68001013
+#define MASK_SBINVI  0xfc00707f
+#define MATCH_SBEXTI 0x48005013
+#define MASK_SBEXTI  0xfc00707f
+#define MATCH_GORCI 0x28005013
+#define MASK_GORCI  0xfc00707f
+#define MATCH_GREVI 0x68005013
+#define MASK_GREVI  0xfc00707f
+#define MATCH_CMIX 0x6001033
+#define MASK_CMIX  0x600707f
+#define MATCH_CMOV 0x6005033
+#define MASK_CMOV  0x600707f
+#define MATCH_FSL 0x4001033
+#define MASK_FSL  0x600707f
+#define MATCH_FSR 0x4005033
+#define MASK_FSR  0x600707f
+#define MATCH_FSRI 0x4005013
+#define MASK_FSRI  0x400707f
+#define MATCH_CLZ 0x60001013
+#define MASK_CLZ  0xfff0707f
+#define MATCH_CTZ 0x60101013
+#define MASK_CTZ  0xfff0707f
+#define MATCH_PCNT 0x60201013
+#define MASK_PCNT  0xfff0707f
+#define MATCH_SEXT_B 0x60401013
+#define MASK_SEXT_B  0xfff0707f
+#define MATCH_SEXT_H 0x60501013
+#define MASK_SEXT_H  0xfff0707f
+#define MATCH_CRC32_B 0x61001013
+#define MASK_CRC32_B  0xfff0707f
+#define MATCH_CRC32_H 0x61101013
+#define MASK_CRC32_H  0xfff0707f
+#define MATCH_CRC32_W 0x61201013
+#define MASK_CRC32_W  0xfff0707f
+#define MATCH_CRC32C_B 0x61801013
+#define MASK_CRC32C_B  0xfff0707f
+#define MATCH_CRC32C_H 0x61901013
+#define MASK_CRC32C_H  0xfff0707f
+#define MATCH_CRC32C_W 0x61a01013
+#define MASK_CRC32C_W  0xfff0707f
+#define MATCH_SH1ADD 0x20002033
+#define MASK_SH1ADD  0xfe00707f
+#define MATCH_SH2ADD 0x20004033
+#define MASK_SH2ADD  0xfe00707f
+#define MATCH_SH3ADD 0x20006033
+#define MASK_SH3ADD  0xfe00707f
+#define MATCH_CLMUL 0xa001033
+#define MASK_CLMUL  0xfe00707f
+#define MATCH_CLMULR 0xa002033
+#define MASK_CLMULR  0xfe00707f
+#define MATCH_CLMULH 0xa003033
+#define MASK_CLMULH  0xfe00707f
+#define MATCH_MIN 0xa004033
+#define MASK_MIN  0xfe00707f
+#define MATCH_MAX 0xa006033
+#define MASK_MAX  0xfe00707f
+#define MATCH_MINU 0xa005033
+#define MASK_MINU  0xfe00707f
+#define MATCH_MAXU 0xa007033
+#define MASK_MAXU  0xfe00707f
+#define MATCH_SHFL 0x8001033
+#define MASK_SHFL  0xfe00707f
+#define MATCH_UNSHFL 0x8005033
+#define MASK_UNSHFL  0xfe00707f
+#define MATCH_BEXT 0x8006033
+#define MASK_BEXT  0xfe00707f
+#define MATCH_BDEP 0x48006033
+#define MASK_BDEP  0xfe00707f
+#define MATCH_PACK 0x8004033
+#define MASK_PACK  0xfe00707f
+#define MATCH_PACKU 0x48004033
+#define MASK_PACKU  0xfe00707f
+#define MATCH_PACKH 0x8007033
+#define MASK_PACKH  0xfe00707f
+#define MATCH_BFP 0x48007033
+#define MASK_BFP  0xfe00707f
+#define MATCH_SHFLI 0x8001013
+#define MASK_SHFLI  0xfe00707f
+#define MATCH_UNSHFLI 0x8005013
+#define MASK_UNSHFLI  0xfe00707f
+#define MATCH_BMATFLIP 0x60301013
+#define MASK_BMATFLIP  0xfff0707f
+#define MATCH_CRC32_D 0x61301013
+#define MASK_CRC32_D  0xfff0707f
+#define MATCH_CRC32C_D 0x61b01013
+#define MASK_CRC32C_D  0xfff0707f
+#define MATCH_BMATOR 0x8003033
+#define MASK_BMATOR  0xfe00707f
+#define MATCH_BMATXOR 0x48003033
+#define MASK_BMATXOR  0xfe00707f
+#define MATCH_SLLIU_W 0x800101b
+#define MASK_SLLIU_W  0xfc00707f
+#define MATCH_ADDU_W 0x800003b
+#define MASK_ADDU_W  0xfe00707f
+#define MATCH_ROLW 0x6000103b
+#define MASK_ROLW  0xfe00707f
+#define MATCH_RORW 0x6000503b
+#define MASK_RORW  0xfe00707f
+#define MATCH_SBCLRW 0x4800103b
+#define MASK_SBCLRW  0xfe00707f
+#define MATCH_SBSETW 0x2800103b
+#define MASK_SBSETW  0xfe00707f
+#define MATCH_SBINVW 0x6800103b
+#define MASK_SBINVW  0xfe00707f
+#define MATCH_SBEXTW 0x4800503b
+#define MASK_SBEXTW  0xfe00707f
+#define MATCH_GORCW 0x2800503b
+#define MASK_GORCW  0xfe00707f
+#define MATCH_GREVW 0x6800503b
+#define MASK_GREVW  0xfe00707f
+#define MATCH_RORIW 0x6000501b
+#define MASK_RORIW  0xfe00707f
+#define MATCH_SBCLRIW 0x4800101b
+#define MASK_SBCLRIW  0xfe00707f
+#define MATCH_SBSETIW 0x2800101b
+#define MASK_SBSETIW  0xfe00707f
+#define MATCH_SBINVIW 0x6800101b
+#define MASK_SBINVIW  0xfe00707f
+#define MATCH_GORCIW 0x2800501b
+#define MASK_GORCIW  0xfe00707f
+#define MATCH_GREVIW 0x6800501b
+#define MASK_GREVIW  0xfe00707f
+#define MATCH_FSLW 0x400103b
+#define MASK_FSLW  0x600707f
+#define MATCH_FSRW 0x400503b
+#define MASK_FSRW  0x600707f
+#define MATCH_FSRIW 0x400501b
+#define MASK_FSRIW  0x600707f
+#define MATCH_CLZW 0x6000101b
+#define MASK_CLZW  0xfff0707f
+#define MATCH_CTZW 0x6010101b
+#define MASK_CTZW  0xfff0707f
+#define MATCH_PCNTW 0x6020101b
+#define MASK_PCNTW  0xfff0707f
+#define MATCH_SH1ADDU_W 0x2000203b
+#define MASK_SH1ADDU_W  0xfe00707f
+#define MATCH_SH2ADDU_W 0x2000403b
+#define MASK_SH2ADDU_W  0xfe00707f
+#define MATCH_SH3ADDU_W 0x2000603b
+#define MASK_SH3ADDU_W  0xfe00707f
+#define MATCH_SHFLW 0x800103b
+#define MASK_SHFLW  0xfe00707f
+#define MATCH_UNSHFLW 0x800503b
+#define MASK_UNSHFLW  0xfe00707f
+#define MATCH_BEXTW 0x800603b
+#define MASK_BEXTW  0xfe00707f
+#define MATCH_BDEPW 0x4800603b
+#define MASK_BDEPW  0xfe00707f
+#define MATCH_PACKW 0x800403b
+#define MASK_PACKW  0xfe00707f
+#define MATCH_PACKUW 0x4800403b
+#define MASK_PACKUW  0xfe00707f
+#define MATCH_BFPW 0x4800703b
+#define MASK_BFPW  0xfe00707f
+#define MATCH_XPERMN 0x28002033
+#define MASK_XPERMN  0xfe00707f
+#define MATCH_XPERMB 0x28004033
+#define MASK_XPERMB  0xfe00707f
+#define MATCH_XPERMH 0x28003033
+#define MASK_XPERMH  0xfe00707f
+#define MATCH_XPERMW 0x28000033
+#define MASK_XPERMW  0xfe00707f
+
 #define MATCH_AMOADD_W 0x202f
 #define MASK_AMOADD_W  0xf800707f
 #define MATCH_AMOXOR_W 0x2000202f
@@ -927,6 +1118,102 @@ DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW)
 DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW)
 DECLARE_INSN(remw, MATCH_REMW, MASK_REMW)
 DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW)
+DECLARE_INSN(andn, MATCH_ANDN, MASK_ANDN)
+DECLARE_INSN(orn, MATCH_ORN, MASK_ORN)
+DECLARE_INSN(xnor, MATCH_XNOR, MASK_XNOR)
+DECLARE_INSN(rol, MATCH_ROL, MASK_ROL)
+DECLARE_INSN(ror, MATCH_ROR, MASK_ROR)
+DECLARE_INSN(sbclr, MATCH_SBCLR, MASK_SBCLR)
+DECLARE_INSN(sbset, MATCH_SBSET, MASK_SBSET)
+DECLARE_INSN(sbinv, MATCH_SBINV, MASK_SBINV)
+DECLARE_INSN(sbext, MATCH_SBEXT, MASK_SBEXT)
+DECLARE_INSN(gorc, MATCH_GORC, MASK_GORC)
+DECLARE_INSN(grev, MATCH_GREV, MASK_GREV)
+DECLARE_INSN(rori, MATCH_RORI, MASK_RORI)
+DECLARE_INSN(sbclri, MATCH_SBCLRI, MASK_SBCLRI)
+DECLARE_INSN(sbseti, MATCH_SBSETI, MASK_SBSETI)
+DECLARE_INSN(sbinvi, MATCH_SBINVI, MASK_SBINVI)
+DECLARE_INSN(sbexti, MATCH_SBEXTI, MASK_SBEXTI)
+DECLARE_INSN(gorci, MATCH_GORCI, MASK_GORCI)
+DECLARE_INSN(grevi, MATCH_GREVI, MASK_GREVI)
+DECLARE_INSN(cmix, MATCH_CMIX, MASK_CMIX)
+DECLARE_INSN(cmov, MATCH_CMOV, MASK_CMOV)
+DECLARE_INSN(fsl, MATCH_FSL, MASK_FSL)
+DECLARE_INSN(fsr, MATCH_FSR, MASK_FSR)
+DECLARE_INSN(fsri, MATCH_FSRI, MASK_FSRI)
+DECLARE_INSN(clz, MATCH_CLZ, MASK_CLZ)
+DECLARE_INSN(ctz, MATCH_CTZ, MASK_CTZ)
+DECLARE_INSN(pcnt, MATCH_PCNT, MASK_PCNT)
+DECLARE_INSN(sext_b, MATCH_SEXT_B, MASK_SEXT_B)
+DECLARE_INSN(sext_h, MATCH_SEXT_H, MASK_SEXT_H)
+DECLARE_INSN(crc32_b, MATCH_CRC32_B, MASK_CRC32_B)
+DECLARE_INSN(crc32_h, MATCH_CRC32_H, MASK_CRC32_H)
+DECLARE_INSN(crc32_w, MATCH_CRC32_W, MASK_CRC32_W)
+DECLARE_INSN(crc32c_b, MATCH_CRC32C_B, MASK_CRC32C_B)
+DECLARE_INSN(crc32c_h, MATCH_CRC32C_H, MASK_CRC32C_H)
+DECLARE_INSN(crc32c_w, MATCH_CRC32C_W, MASK_CRC32C_W)
+DECLARE_INSN(sh1add, MATCH_SH1ADD, MASK_SH1ADD)
+DECLARE_INSN(sh2add, MATCH_SH2ADD, MASK_SH2ADD)
+DECLARE_INSN(sh3add, MATCH_SH3ADD, MASK_SH3ADD)
+DECLARE_INSN(clmul, MATCH_CLMUL, MASK_CLMUL)
+DECLARE_INSN(clmulr, MATCH_CLMULR, MASK_CLMULR)
+DECLARE_INSN(clmulh, MATCH_CLMULH, MASK_CLMULH)
+DECLARE_INSN(min, MATCH_MIN, MASK_MIN)
+DECLARE_INSN(max, MATCH_MAX, MASK_MAX)
+DECLARE_INSN(minu, MATCH_MINU, MASK_MINU)
+DECLARE_INSN(maxu, MATCH_MAXU, MASK_MAXU)
+DECLARE_INSN(shfl, MATCH_SHFL, MASK_SHFL)
+DECLARE_INSN(unshfl, MATCH_UNSHFL, MASK_UNSHFL)
+DECLARE_INSN(bext, MATCH_BEXT, MASK_BEXT)
+DECLARE_INSN(bdep, MATCH_BDEP, MASK_BDEP)
+DECLARE_INSN(pack, MATCH_PACK, MASK_PACK)
+DECLARE_INSN(packu, MATCH_PACKU, MASK_PACKU)
+DECLARE_INSN(packh, MATCH_PACKH, MASK_PACKH)
+DECLARE_INSN(bfp, MATCH_BFP, MASK_BFP)
+DECLARE_INSN(shfli, MATCH_SHFLI, MASK_SHFLI)
+DECLARE_INSN(unshfli, MATCH_UNSHFLI, MASK_UNSHFLI)
+DECLARE_INSN(bmatflip, MATCH_BMATFLIP, MASK_BMATFLIP)
+DECLARE_INSN(crc32_d, MATCH_CRC32_D, MASK_CRC32_D)
+DECLARE_INSN(crc32c_d, MATCH_CRC32C_D, MASK_CRC32C_D)
+DECLARE_INSN(bmator, MATCH_BMATOR, MASK_BMATOR)
+DECLARE_INSN(bmatxor, MATCH_BMATXOR, MASK_BMATXOR)
+DECLARE_INSN(slliu_w, MATCH_SLLIU_W, MASK_SLLIU_W)
+DECLARE_INSN(addu_w, MATCH_ADDU_W, MASK_ADDU_W)
+DECLARE_INSN(rolw, MATCH_ROLW, MASK_ROLW)
+DECLARE_INSN(rorw, MATCH_RORW, MASK_RORW)
+DECLARE_INSN(sbclrw, MATCH_SBCLRW, MASK_SBCLRW)
+DECLARE_INSN(sbsetw, MATCH_SBSETW, MASK_SBSETW)
+DECLARE_INSN(sbinvw, MATCH_SBINVW, MASK_SBINVW)
+DECLARE_INSN(sbextw, MATCH_SBEXTW, MASK_SBEXTW)
+DECLARE_INSN(gorcw, MATCH_GORCW, MASK_GORCW)
+DECLARE_INSN(grevw, MATCH_GREVW, MASK_GREVW)
+DECLARE_INSN(roriw, MATCH_RORIW, MASK_RORIW)
+DECLARE_INSN(sbclriw, MATCH_SBCLRIW, MASK_SBCLRIW)
+DECLARE_INSN(sbsetiw, MATCH_SBSETIW, MASK_SBSETIW)
+DECLARE_INSN(sbinviw, MATCH_SBINVIW, MASK_SBINVIW)
+DECLARE_INSN(gorciw, MATCH_GORCIW, MASK_GORCIW)
+DECLARE_INSN(greviw, MATCH_GREVIW, MASK_GREVIW)
+DECLARE_INSN(fslw, MATCH_FSLW, MASK_FSLW)
+DECLARE_INSN(fsrw, MATCH_FSRW, MASK_FSRW)
+DECLARE_INSN(fsriw, MATCH_FSRIW, MASK_FSRIW)
+DECLARE_INSN(clzw, MATCH_CLZW, MASK_CLZW)
+DECLARE_INSN(ctzw, MATCH_CTZW, MASK_CTZW)
+DECLARE_INSN(pcntw, MATCH_PCNTW, MASK_PCNTW)
+DECLARE_INSN(sh1addu_w, MATCH_SH1ADDU_W, MASK_SH1ADDU_W)
+DECLARE_INSN(sh2addu_w, MATCH_SH2ADDU_W, MASK_SH2ADDU_W)
+DECLARE_INSN(sh3addu_w, MATCH_SH3ADDU_W, MASK_SH3ADDU_W)
+DECLARE_INSN(shflw, MATCH_SHFLW, MASK_SHFLW)
+DECLARE_INSN(unshflw, MATCH_UNSHFLW, MASK_UNSHFLW)
+DECLARE_INSN(bextw, MATCH_BEXTW, MASK_BEXTW)
+DECLARE_INSN(bdepw, MATCH_BDEPW, MASK_BDEPW)
+DECLARE_INSN(packw, MATCH_PACKW, MASK_PACKW)
+DECLARE_INSN(packuw, MATCH_PACKUW, MASK_PACKUW)
+DECLARE_INSN(bfpw, MATCH_BFPW, MASK_BFPW)
+DECLARE_INSN(xperm.n, MATCH_XPERMN, MASK_XPERMN)
+DECLARE_INSN(xperm.b, MATCH_XPERMB, MASK_XPERMB)
+DECLARE_INSN(xperm.h, MATCH_XPERMH, MASK_XPERMH)
+DECLARE_INSN(xperm.w, MATCH_XPERMW, MASK_XPERMW)
+
 DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
 DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)
 DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 1949072..0255feb 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -307,10 +307,23 @@ enum riscv_insn_class
    INSN_CLASS_F,
    INSN_CLASS_D,
    INSN_CLASS_Q,
+   INSN_CLASS_B,
    INSN_CLASS_F_AND_C,
    INSN_CLASS_D_AND_C,
    INSN_CLASS_ZICSR,
    INSN_CLASS_ZIFENCEI,
+   INSN_CLASS_B_OR_ZBA,
+   INSN_CLASS_B_OR_ZBB,
+   INSN_CLASS_B_OR_ZBC,
+   INSN_CLASS_B_OR_ZBE,
+   INSN_CLASS_B_OR_ZBF,
+   INSN_CLASS_B_OR_ZBM,
+   INSN_CLASS_B_OR_ZBP,
+   INSN_CLASS_ZBR,
+   INSN_CLASS_B_OR_ZBS,
+   INSN_CLASS_ZBT,
+   INSN_CLASS_B_OR_ZBB_OR_ZBP,
+   INSN_CLASS_B_OR_ZBF_OR_ZBP
   };
 
 /* This structure holds information for a particular instruction.  */
@@ -353,7 +366,8 @@ enum riscv_isa_spec_class
 
   ISA_SPEC_CLASS_2P2,
   ISA_SPEC_CLASS_20190608,
-  ISA_SPEC_CLASS_20191213
+  ISA_SPEC_CLASS_20191213,
+  ISA_SPEC_CLASS_DRAFT
 };
 
 #define RISCV_UNKNOWN_VERSION -1
@@ -484,6 +498,7 @@ enum
   M_ZEXTW,
   M_SEXTB,
   M_SEXTH,
+  M_PERM,
   M_NUM_MACROS
 };
 
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index ca3b110..aaa8060 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -245,6 +245,7 @@ print_insn_args (const char *d, insn_t l, bfd_vma pc, disassemble_info *info)
 	    case '>':
 	      print (info->stream, "0x%x", (int)EXTRACT_RVC_IMM (l) & 0x3f);
 	      break;
+	    case '|':
 	    case '<':
 	      print (info->stream, "0x%x", (int)EXTRACT_RVC_IMM (l) & 0x1f);
 	      break;
@@ -285,6 +286,11 @@ print_insn_args (const char *d, insn_t l, bfd_vma pc, disassemble_info *info)
 		 riscv_gpr_names[EXTRACT_OPERAND (RS2, l)]);
 	  break;
 
+	case 'r':
+	  print (info->stream, "%s",
+		 riscv_gpr_names[EXTRACT_OPERAND (RS3, l)]);
+	  break;
+
 	case 'u':
 	  print (info->stream, "0x%x",
 		 (unsigned)EXTRACT_UTYPE_IMM (l) >> RISCV_IMM_BITS);
@@ -348,6 +354,7 @@ print_insn_args (const char *d, insn_t l, bfd_vma pc, disassemble_info *info)
 	  print (info->stream, "0x%x", (int)EXTRACT_OPERAND (SHAMT, l));
 	  break;
 
+	case '|':
 	case '<':
 	  print (info->stream, "0x%x", (int)EXTRACT_OPERAND (SHAMTW, l));
 	  break;
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index f90d717..bf8b27a 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -238,10 +238,7 @@ const struct riscv_opcode riscv_opcodes[] =
 {"mv",          0, INSN_CLASS_I,   "d,s",  MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS },
 {"move",        0, INSN_CLASS_C,   "d,CV",  MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS },
 {"move",        0, INSN_CLASS_I,   "d,s",  MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS },
-{"sext.b",      0, INSN_CLASS_I,   "d,s",  0,    (int) M_SEXTB,  match_never, INSN_MACRO },
-{"sext.h",      0, INSN_CLASS_I,   "d,s",  0,    (int) M_SEXTH,  match_never, INSN_MACRO },
 {"zext.b",      0, INSN_CLASS_I,   "d,s",  MATCH_ANDI | ENCODE_ITYPE_IMM (255), MASK_ANDI | MASK_IMM, match_opcode, INSN_ALIAS },
-{"zext.h",      0, INSN_CLASS_I,   "d,s",  0,    (int) M_ZEXTH,  match_never, INSN_MACRO },
 {"andi",        0, INSN_CLASS_C,   "Cs,Cw,Co",  MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS },
 {"andi",        0, INSN_CLASS_I,   "d,s,j",  MATCH_ANDI, MASK_ANDI, match_opcode, 0 },
 {"and",         0, INSN_CLASS_C,   "Cs,Cw,Ct",  MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS },
@@ -374,7 +371,6 @@ const struct riscv_opcode riscv_opcodes[] =
 {"sd",         64, INSN_CLASS_C, "Ct,Cl(Cs)",  MATCH_C_SD, MASK_C_SD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
 {"sd",         64, INSN_CLASS_I, "t,q(s)",  MATCH_SD, MASK_SD, match_opcode, INSN_DREF|INSN_8_BYTE },
 {"sd",         64, INSN_CLASS_I, "t,A,s",  0, (int) M_SD, match_never, INSN_MACRO },
-{"zext.w",     64, INSN_CLASS_I, "d,s",    0, (int) M_ZEXTW,  match_never, INSN_MACRO },
 {"sext.w",     64, INSN_CLASS_C, "d,CU",  MATCH_C_ADDIW, MASK_C_ADDIW | MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS },
 {"sext.w",     64, INSN_CLASS_I, "d,s",  MATCH_ADDIW, MASK_ADDIW | MASK_IMM, match_opcode, INSN_ALIAS },
 {"addiw",      64, INSN_CLASS_C, "d,CU,Co",  MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS },
@@ -502,6 +498,213 @@ const struct riscv_opcode riscv_opcodes[] =
 {"remw",     64, INSN_CLASS_M, "d,s,t",  MATCH_REMW, MASK_REMW, match_opcode, 0 },
 {"remuw",    64, INSN_CLASS_M, "d,s,t",  MATCH_REMUW, MASK_REMUW, match_opcode, 0 },
 
+/* Bitmanip instruction subset  */
+{"sh1add",    0, INSN_CLASS_B_OR_ZBA,   "d,s,t",  MATCH_SH1ADD, MASK_SH1ADD, match_opcode, 0 },
+{"sh2add",    0, INSN_CLASS_B_OR_ZBA,   "d,s,t",  MATCH_SH2ADD, MASK_SH2ADD, match_opcode, 0 },
+{"sh3add",    0, INSN_CLASS_B_OR_ZBA,   "d,s,t",  MATCH_SH3ADD, MASK_SH3ADD, match_opcode, 0 },
+{"slliu.w",  64, INSN_CLASS_B_OR_ZBA,   "d,s,>",  MATCH_SLLIU_W, MASK_SLLIU_W, match_opcode, 0 },
+{"zext.w",   64, INSN_CLASS_B_OR_ZBB,   "d,s",  MATCH_ADDU_W, MASK_ADDU_W | MASK_RS2, match_opcode, INSN_ALIAS },
+{"zext.w",   64, INSN_CLASS_I,          "d,s",    0, (int) M_ZEXTW,  match_never, INSN_MACRO },
+{"addu.w",   64, INSN_CLASS_B_OR_ZBA,   "d,s,t",  MATCH_ADDU_W, MASK_ADDU_W, match_opcode, 0 },
+{"sh1addu.w",64, INSN_CLASS_B_OR_ZBA,   "d,s,t",  MATCH_SH1ADDU_W, MASK_SH1ADDU_W, match_opcode, 0 },
+{"sh2addu.w",64, INSN_CLASS_B_OR_ZBA,   "d,s,t",  MATCH_SH2ADDU_W, MASK_SH2ADDU_W, match_opcode, 0 },
+{"sh3addu.w",64, INSN_CLASS_B_OR_ZBA,   "d,s,t",  MATCH_SH3ADDU_W, MASK_SH3ADDU_W, match_opcode, 0 },
+
+{"clz",       0, INSN_CLASS_B_OR_ZBB,   "d,s",  MATCH_CLZ, MASK_CLZ, match_opcode, 0 },
+{"ctz",       0, INSN_CLASS_B_OR_ZBB,   "d,s",  MATCH_CTZ, MASK_CTZ, match_opcode, 0 },
+{"pcnt",      0, INSN_CLASS_B_OR_ZBB,   "d,s",  MATCH_PCNT, MASK_PCNT, match_opcode, 0 },
+{"min",       0, INSN_CLASS_B_OR_ZBB,   "d,s,t",  MATCH_MIN, MASK_MIN, match_opcode, 0 },
+{"max",       0, INSN_CLASS_B_OR_ZBB,   "d,s,t",  MATCH_MAX, MASK_MAX, match_opcode, 0 },
+{"minu",      0, INSN_CLASS_B_OR_ZBB,   "d,s,t",  MATCH_MINU, MASK_MINU, match_opcode, 0 },
+{"maxu",      0, INSN_CLASS_B_OR_ZBB,   "d,s,t",  MATCH_MAXU, MASK_MAXU, match_opcode, 0 },
+{"sext.b",    0, INSN_CLASS_B_OR_ZBB,   "d,s",  MATCH_SEXT_B, MASK_SEXT_B, match_opcode, 0 },
+{"sext.b",    0, INSN_CLASS_I,          "d,s",  0, (int) M_SEXTB,  match_never, INSN_MACRO },
+{"sext.h",    0, INSN_CLASS_B_OR_ZBB,   "d,s",  MATCH_SEXT_H, MASK_SEXT_H, match_opcode, 0 },
+{"sext.h",    0, INSN_CLASS_I,          "d,s",  0, (int) M_SEXTH,  match_never, INSN_MACRO },
+{"zext.h",   32, INSN_CLASS_B_OR_ZBB,   "d,s",  MATCH_PACK, MASK_PACK | MASK_RS2, match_opcode, INSN_ALIAS },
+{"zext.h",   64, INSN_CLASS_B_OR_ZBB,   "d,s",  MATCH_PACKW, MASK_PACKW | MASK_RS2, match_opcode, INSN_ALIAS },
+{"zext.h",    0, INSN_CLASS_I,          "d,s",  0, (int) M_ZEXTH,  match_never, INSN_MACRO },
+{"andn",      0, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s,t",  MATCH_ANDN, MASK_ANDN, match_opcode, 0 },
+{"orn",       0, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s,t",  MATCH_ORN, MASK_ORN, match_opcode, 0 },
+{"xnor",      0, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s,t",  MATCH_XNOR, MASK_XNOR, match_opcode, 0 },
+{"rori",      0, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s,>",  MATCH_RORI, MASK_RORI, match_opcode, 0 },
+{"ror",       0, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s,t",  MATCH_ROR, MASK_ROR, match_opcode, 0 },
+{"ror",       0, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s,>",  MATCH_RORI, MASK_RORI, match_opcode, INSN_ALIAS },
+{"rol",       0, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s,t",  MATCH_ROL, MASK_ROL, match_opcode, 0 },
+{"clzw",     64, INSN_CLASS_B_OR_ZBB,   "d,s",  MATCH_CLZW, MASK_CLZW, match_opcode, 0 },
+{"ctzw",     64, INSN_CLASS_B_OR_ZBB,   "d,s",  MATCH_CTZW, MASK_CTZW, match_opcode, 0 },
+{"pcntw",    64, INSN_CLASS_B_OR_ZBB,   "d,s",  MATCH_PCNTW, MASK_PCNTW, match_opcode, 0 },
+{"roriw",    64, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s,<",  MATCH_RORIW, MASK_RORIW, match_opcode, 0 },
+{"rorw",     64, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s,t",  MATCH_RORW, MASK_RORW, match_opcode, 0 },
+{"rorw",     64, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s,<",  MATCH_RORIW, MASK_RORIW, match_opcode, INSN_ALIAS },
+{"rolw",     64, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s,t",  MATCH_ROLW, MASK_ROLW, match_opcode, 0 },
+
+{"gorci",     0, INSN_CLASS_B_OR_ZBP,   "d,s,>",  MATCH_GORCI, MASK_GORCI, match_opcode, 0 },
+{"grevi",     0, INSN_CLASS_B_OR_ZBP,   "d,s,>",  MATCH_GREVI, MASK_GREVI, match_opcode, 0 },
+{"gorc",      0, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_GORC, MASK_GORC, match_opcode, 0 },
+{"gorc",      0, INSN_CLASS_B_OR_ZBP,   "d,s,>",  MATCH_GORCI, MASK_GORCI, match_opcode, INSN_ALIAS },
+{"grev",      0, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_GREV, MASK_GREV, match_opcode, 0 },
+{"grev",      0, INSN_CLASS_B_OR_ZBP,   "d,s,>",  MATCH_GREVI, MASK_GREVI, match_opcode, INSN_ALIAS },
+{"shfli",     0, INSN_CLASS_B_OR_ZBP,   "d,s,|",  MATCH_SHFLI, MASK_SHFLI, match_opcode, 0 },
+{"unshfli",   0, INSN_CLASS_B_OR_ZBP,   "d,s,|",  MATCH_UNSHFLI, MASK_UNSHFLI, match_opcode, 0 },
+{"shfl",      0, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_SHFL, MASK_SHFL, match_opcode, 0 },
+{"shfl",      0, INSN_CLASS_B_OR_ZBP,   "d,s,|",  MATCH_SHFLI, MASK_SHFLI, match_opcode, INSN_ALIAS },
+{"unshfl",    0, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_UNSHFL, MASK_UNSHFL, match_opcode, 0 },
+{"unshfl",    0, INSN_CLASS_B_OR_ZBP,   "d,s,|",  MATCH_UNSHFLI, MASK_UNSHFLI, match_opcode, INSN_ALIAS },
+{"pack",      0, INSN_CLASS_B_OR_ZBF_OR_ZBP,   "d,s,t",  MATCH_PACK, MASK_PACK, match_opcode, 0 },
+{"packu",     0, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_PACKU, MASK_PACKU, match_opcode, 0 },
+{"packh",     0, INSN_CLASS_B_OR_ZBF_OR_ZBP,   "d,s,t",  MATCH_PACKH, MASK_PACKH, match_opcode, 0 },
+{"xperm.n",   0, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_XPERMN, MASK_XPERMN, match_opcode, 0 },
+{"xperm.b",   0, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_XPERMB, MASK_XPERMB, match_opcode, 0 },
+{"xperm.h",   0, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_XPERMH, MASK_XPERMH, match_opcode, 0 },
+{"gorciw",   64, INSN_CLASS_B_OR_ZBP,   "d,s,<",  MATCH_GORCIW, MASK_GORCIW, match_opcode, 0 },
+{"greviw",   64, INSN_CLASS_B_OR_ZBP,   "d,s,<",  MATCH_GREVIW, MASK_GREVIW, match_opcode, 0 },
+{"gorcw",    64, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_GORCW, MASK_GORCW, match_opcode, 0 },
+{"gorcw",    64, INSN_CLASS_B_OR_ZBP,   "d,s,<",  MATCH_GORCIW, MASK_GORCIW, match_opcode, INSN_ALIAS },
+{"grevw",    64, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_GREVW, MASK_GREVW, match_opcode, 0 },
+{"grevw",    64, INSN_CLASS_B_OR_ZBP,   "d,s,<",  MATCH_GREVIW, MASK_GREVIW, match_opcode, INSN_ALIAS },
+{"shflw",    64, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_SHFLW, MASK_SHFLW, match_opcode, 0 },
+{"unshflw",  64, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_UNSHFLW, MASK_UNSHFLW, match_opcode, 0 },
+{"packw",    64, INSN_CLASS_B_OR_ZBF_OR_ZBP,   "d,s,t",  MATCH_PACKW, MASK_PACKW, match_opcode, 0 },
+{"packuw",   64, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_PACKUW, MASK_PACKUW, match_opcode, 0 },
+{"xperm.w",  64, INSN_CLASS_B_OR_ZBP,   "d,s,t",  MATCH_XPERMW, MASK_XPERMW, match_opcode, 0 },
+
+{"bfp",       0, INSN_CLASS_B_OR_ZBF,   "d,s,t",  MATCH_BFP, MASK_BFP, match_opcode, 0 },
+{"bfpw",     64, INSN_CLASS_B_OR_ZBF,   "d,s,t",  MATCH_BFPW, MASK_BFPW, match_opcode, 0 },
+
+{"clmul",     0, INSN_CLASS_B_OR_ZBC,   "d,s,t",  MATCH_CLMUL, MASK_CLMUL, match_opcode, 0 },
+{"clmulh",    0, INSN_CLASS_B_OR_ZBC,   "d,s,t",  MATCH_CLMULH, MASK_CLMULH, match_opcode, 0 },
+{"clmulr",    0, INSN_CLASS_B_OR_ZBC,   "d,s,t",  MATCH_CLMULR, MASK_CLMULR, match_opcode, 0 },
+
+{"bdep",      0, INSN_CLASS_B_OR_ZBE,   "d,s,t",  MATCH_BDEP, MASK_BDEP, match_opcode, 0 },
+{"bext",      0, INSN_CLASS_B_OR_ZBE,   "d,s,t",  MATCH_BEXT, MASK_BEXT, match_opcode, 0 },
+{"bdepw",    64, INSN_CLASS_B_OR_ZBE,   "d,s,t",  MATCH_BDEPW, MASK_BDEPW, match_opcode, 0 },
+{"bextw",    64, INSN_CLASS_B_OR_ZBE,   "d,s,t",  MATCH_BEXTW, MASK_BEXTW, match_opcode, 0 },
+
+{"bmatflip", 64, INSN_CLASS_B_OR_ZBM,   "d,s",  MATCH_BMATFLIP, MASK_BMATFLIP, match_opcode, 0 },
+{"bmator",   64, INSN_CLASS_B_OR_ZBM,   "d,s,t",  MATCH_BMATOR, MASK_BMATOR, match_opcode, 0 },
+{"bmatxor",  64, INSN_CLASS_B_OR_ZBM,   "d,s,t",  MATCH_BMATXOR, MASK_BMATXOR, match_opcode, 0 },
+
+{"crc32.b",   0, INSN_CLASS_ZBR,   "d,s",  MATCH_CRC32_B, MASK_CRC32_B, match_opcode, 0 },
+{"crc32.h",   0, INSN_CLASS_ZBR,   "d,s",  MATCH_CRC32_H, MASK_CRC32_H, match_opcode, 0 },
+{"crc32.w",   0, INSN_CLASS_ZBR,   "d,s",  MATCH_CRC32_W, MASK_CRC32_W, match_opcode, 0 },
+{"crc32c.b",  0, INSN_CLASS_ZBR,   "d,s",  MATCH_CRC32C_B, MASK_CRC32C_B, match_opcode, 0 },
+{"crc32c.h",  0, INSN_CLASS_ZBR,   "d,s",  MATCH_CRC32C_H, MASK_CRC32C_H, match_opcode, 0 },
+{"crc32c.w",  0, INSN_CLASS_ZBR,   "d,s",  MATCH_CRC32C_W, MASK_CRC32C_W, match_opcode, 0 },
+{"crc32.d",  64, INSN_CLASS_ZBR,   "d,s",  MATCH_CRC32_D, MASK_CRC32_D, match_opcode, 0 },
+{"crc32c.d", 64, INSN_CLASS_ZBR,   "d,s",  MATCH_CRC32C_D, MASK_CRC32C_D, match_opcode, 0 },
+
+{"sbclri",    0, INSN_CLASS_B_OR_ZBS,   "d,s,>",  MATCH_SBCLRI, MASK_SBCLRI, match_opcode, 0 },
+{"sbseti",    0, INSN_CLASS_B_OR_ZBS,   "d,s,>",  MATCH_SBSETI, MASK_SBSETI, match_opcode, 0 },
+{"sbinvi",    0, INSN_CLASS_B_OR_ZBS,   "d,s,>",  MATCH_SBINVI, MASK_SBINVI, match_opcode, 0 },
+{"sbexti",    0, INSN_CLASS_B_OR_ZBS,   "d,s,>",  MATCH_SBEXTI, MASK_SBEXTI, match_opcode, 0 },
+{"sbclr",     0, INSN_CLASS_B_OR_ZBS,   "d,s,t",  MATCH_SBCLR, MASK_SBCLR, match_opcode, 0 },
+{"sbclr",     0, INSN_CLASS_B_OR_ZBS,   "d,s,>",  MATCH_SBCLRI, MASK_SBCLRI, match_opcode, INSN_ALIAS },
+{"sbset",     0, INSN_CLASS_B_OR_ZBS,   "d,s,t",  MATCH_SBSET, MASK_SBSET, match_opcode, 0 },
+{"sbset",     0, INSN_CLASS_B_OR_ZBS,   "d,s,>",  MATCH_SBSETI, MASK_SBSETI, match_opcode, INSN_ALIAS },
+{"sbinv",     0, INSN_CLASS_B_OR_ZBS,   "d,s,t",  MATCH_SBINV, MASK_SBINV, match_opcode, 0 },
+{"sbinv",     0, INSN_CLASS_B_OR_ZBS,   "d,s,>",  MATCH_SBINVI, MASK_SBINVI, match_opcode, INSN_ALIAS },
+{"sbext",     0, INSN_CLASS_B_OR_ZBS,   "d,s,t",  MATCH_SBEXT, MASK_SBEXT, match_opcode, 0 },
+{"sbext",     0, INSN_CLASS_B_OR_ZBS,   "d,s,>",  MATCH_SBEXTI, MASK_SBEXTI, match_opcode, INSN_ALIAS },
+{"sbclriw",  64, INSN_CLASS_B_OR_ZBS,   "d,s,<",  MATCH_SBCLRIW, MASK_SBCLRIW, match_opcode, 0 },
+{"sbsetiw",  64, INSN_CLASS_B_OR_ZBS,   "d,s,<",  MATCH_SBSETIW, MASK_SBSETIW, match_opcode, 0 },
+{"sbinviw",  64, INSN_CLASS_B_OR_ZBS,   "d,s,<",  MATCH_SBINVIW, MASK_SBINVIW, match_opcode, 0 },
+{"sbclrw",   64, INSN_CLASS_B_OR_ZBS,   "d,s,t",  MATCH_SBCLRW, MASK_SBCLRW, match_opcode, 0 },
+{"sbclrw",   64, INSN_CLASS_B_OR_ZBS,   "d,s,<",  MATCH_SBCLRIW, MASK_SBCLRIW, match_opcode, INSN_ALIAS },
+{"sbsetw",   64, INSN_CLASS_B_OR_ZBS,   "d,s,t",  MATCH_SBSETW, MASK_SBSETW, match_opcode, 0 },
+{"sbsetw",   64, INSN_CLASS_B_OR_ZBS,   "d,s,<",  MATCH_SBSETIW, MASK_SBSETIW, match_opcode, INSN_ALIAS },
+{"sbinvw",   64, INSN_CLASS_B_OR_ZBS,   "d,s,t",  MATCH_SBINVW, MASK_SBINVW, match_opcode, 0 },
+{"sbinvw",   64, INSN_CLASS_B_OR_ZBS,   "d,s,<",  MATCH_SBINVIW, MASK_SBINVIW, match_opcode, INSN_ALIAS },
+{"sbextw",   64, INSN_CLASS_B_OR_ZBS,   "d,s,t",  MATCH_SBEXTW, MASK_SBEXTW, match_opcode, 0 },
+
+{"cmix",      0, INSN_CLASS_ZBT,   "d,t,s,r",  MATCH_CMIX, MASK_CMIX, match_opcode, 0 },
+{"cmov",      0, INSN_CLASS_ZBT,   "d,t,s,r",  MATCH_CMOV, MASK_CMOV, match_opcode, 0 },
+{"fsri",      0, INSN_CLASS_ZBT,   "d,s,r,>",  MATCH_FSRI, MASK_FSRI, match_opcode, 0 },
+{"fsl",       0, INSN_CLASS_ZBT,   "d,s,r,t",  MATCH_FSL, MASK_FSL, match_opcode, 0 },
+{"fsr",       0, INSN_CLASS_ZBT,   "d,s,r,t",  MATCH_FSR, MASK_FSR, match_opcode, 0 },
+{"fsr",       0, INSN_CLASS_ZBT,   "d,s,r,>",  MATCH_FSRI, MASK_FSRI, match_opcode, INSN_ALIAS },
+{"fsriw",    64, INSN_CLASS_ZBT,   "d,s,r,<",  MATCH_FSRIW, MASK_FSRIW, match_opcode, 0 },
+{"fslw",     64, INSN_CLASS_ZBT,   "d,s,r,t",  MATCH_FSLW, MASK_FSLW, match_opcode, 0 },
+{"fsrw",     64, INSN_CLASS_ZBT,   "d,s,r,t",  MATCH_FSRW, MASK_FSRW, match_opcode, 0 },
+{"fsrw",     64, INSN_CLASS_ZBT,   "d,s,r,<",  MATCH_FSRIW, MASK_FSRIW, match_opcode, INSN_ALIAS },
+
+/* Bitmanip pseudo-instructions  */
+{"rev.p",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev2.n",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev.n",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev4.b",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev2.b",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev.b",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev8.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev4.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev2.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev.h",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev16.w",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev8.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev4.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev2.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev.w",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev32",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev16",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev8",      0, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev4",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev2",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"rev",       0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+
+{"orc.p",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc2.n",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc.n",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc4.b",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc2.b",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc.b",     0, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc8.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc4.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc2.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc.h",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc16.w",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc8.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc4.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc2.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc.w",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc32",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc16",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc8",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc4",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc2",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"orc",       0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+
+{"zip.n",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip2.b",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip.b",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip4.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip2.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip.h",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip8.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip4.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip2.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip.w",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip16",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip8",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip4",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip2",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"zip",       0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+
+{"unzip.n",   0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip2.b",  0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip.b",   0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip4.h",  0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip2.h",  0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip.h",   0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip8.w", 64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip4.w", 64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip2.w", 64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip.w",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip16",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip8",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip4",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip2",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+{"unzip",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
+
 /* Single-precision floating-point instruction subset */
 {"frcsr",     0, INSN_CLASS_F,   "d",  MATCH_FRCSR, MASK_FRCSR, match_opcode, INSN_ALIAS },
 {"frsr",      0, INSN_CLASS_F,   "d",  MATCH_FRCSR, MASK_FRCSR, match_opcode, INSN_ALIAS },
@@ -926,12 +1129,25 @@ const struct riscv_ext_version riscv_ext_version_table[] =
 {"c", ISA_SPEC_CLASS_20190608, 2, 0},
 {"c", ISA_SPEC_CLASS_2P2,      2, 0},
 
+{"b", ISA_SPEC_CLASS_DRAFT,    0, 92},
+
 {"zicsr", ISA_SPEC_CLASS_20191213, 2, 0},
 {"zicsr", ISA_SPEC_CLASS_20190608, 2, 0},
 
 {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0},
 {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0},
 
+{"zba", ISA_SPEC_CLASS_DRAFT, 0, 92},
+{"zbb", ISA_SPEC_CLASS_DRAFT, 0, 92},
+{"zbc", ISA_SPEC_CLASS_DRAFT, 0, 92},
+{"zbe", ISA_SPEC_CLASS_DRAFT, 0, 92},
+{"zbf", ISA_SPEC_CLASS_DRAFT, 0, 92},
+{"zbm", ISA_SPEC_CLASS_DRAFT, 0, 92},
+{"zbp", ISA_SPEC_CLASS_DRAFT, 0, 92},
+{"zbr", ISA_SPEC_CLASS_DRAFT, 0, 92},
+{"zbs", ISA_SPEC_CLASS_DRAFT, 0, 92},
+{"zbt", ISA_SPEC_CLASS_DRAFT, 0, 92},
+
 /* Terminate the list.  */
 {NULL, 0, 0, 0}
 };
-- 
2.7.4


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

* [PATCH 2/3] RISC-V: Define pseudo rev/orc/zip/unzip as alias instructions.
  2020-12-15 15:11 [PATCH 0/3] RISC-V: Add -menable-experimental-extensions and support bitmanip instructions Nelson Chu
  2020-12-15 15:11 ` [PATCH 1/3] RISC-V: Support riscv " Nelson Chu
@ 2020-12-15 15:11 ` Nelson Chu
  2020-12-15 15:11 ` [PATCH 3/3] RISC-V: Add -menable-experimental-extensions option Nelson Chu
  2020-12-15 18:23 ` [PATCH 0/3] RISC-V: Add -menable-experimental-extensions and support bitmanip instructions Palmer Dabbelt
  3 siblings, 0 replies; 8+ messages in thread
From: Nelson Chu @ 2020-12-15 15:11 UTC (permalink / raw)
  To: binutils, claire, maxim.blinov, jimw, andrew, palmer, kito.cheng

Generally, we usually use INSN_MACRO to expand a pseudo into multiple
instructions; But if the pseudos are one to one mapping, then they are
more like alias instructions, and can use INSN_ALIAS to handle them.
One of the benefits of INSN_ALIAS is that - we can dump the their pseudo
names directly, and it is more friendly to users.

gas/
    * config/tc-riscv.c (macro_build): Removed 'r', '<', '|' and '>'.
    (perm): Removed.
    (macro): Removed rs3, shamt and M_PERM.
    * testsuite/gas/riscv/bitmanip-insns-32.d: Add -Mno-aliases.
    * testsuite/gas/riscv/bitmanip-insns-64.d: Likewise.
    * testsuite/gas/riscv/bitmanip-insns-pseudo-32.d: Updated to show pseudos.
    * testsuite/gas/riscv/bitmanip-insns-pseudo-64.d: Likewise.
    * testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-32.d: New testcase.
    * testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-64.d: Likewise.
include/
    * opcode/riscv.h: Removed M_PERM.
opcodes/
    *riscv-opc.c: Add MATCH/MASK immediate macros for rvb pseudo instructions.
    (riscv_opcodes): Updated and moved the rvb pseudos forward.
---
 gas/config/tc-riscv.c                              |  72 +-----
 gas/testsuite/gas/riscv/bitmanip-insns-32.d        |   2 +-
 gas/testsuite/gas/riscv/bitmanip-insns-64.d        |   2 +-
 gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d | 100 ++++-----
 gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d | 144 ++++++------
 .../gas/riscv/bitmanip-insns-pseudo-noalias-32.d   |  61 +++++
 .../gas/riscv/bitmanip-insns-pseudo-noalias-64.d   |  84 +++++++
 include/opcode/riscv.h                             |   1 -
 opcodes/riscv-opc.c                                | 249 ++++++++++++++-------
 9 files changed, 442 insertions(+), 273 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-32.d
 create mode 100644 gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-64.d

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index ae3a8ad..d3cb941 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -1288,19 +1288,6 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
 	  INSERT_OPERAND (RS2, insn, va_arg (args, int));
 	  continue;
 
-	case 'r':
-	  INSERT_OPERAND (RS3, insn, va_arg (args, int));
-	  continue;
-
-	case '<':
-	case '|':
-	  INSERT_OPERAND (SHAMTW, insn, va_arg (args, int));
-	  continue;
-
-	case '>':
-	  INSERT_OPERAND (SHAMT, insn, va_arg (args, int));
-	  continue;
-
 	case 'j':
 	case 'u':
 	case 'q':
@@ -1498,59 +1485,8 @@ riscv_ext (int destreg, int srcreg, unsigned shift, bfd_boolean sign)
     }
 }
 
-static void
-perm (int rd, int rs1, const char *op)
-{
-  const char *insn = NULL;
-  const char *p = op;
-  int shamt = 0;
-  int shfl = 0;
-
-  switch (p[0])
-    {
-    case 'r': insn = "grevi";   shamt = xlen-1;   p += 3; break;
-    case 'o': insn = "gorci";   shamt = xlen-1;   p += 3; break;
-    case 'z': insn = "shfli";   shamt = xlen/2-1; p += 3; shfl = 1; break;
-    case 'u': insn = "unshfli"; shamt = xlen/2-1; p += 5; shfl = 1; break;
-    default: as_fatal (_("internal error: bad permutation pseudo-instruction %s"), op);
-    }
-
-  switch (p[0])
-    {
-    case '2': shamt &= shamt << 1; p += 1; break;
-    case '4': shamt &= shamt << 2; p += 1; break;
-    case '8': shamt &= shamt << 3; p += 1; break;
-    case '1': shamt &= shamt << 4; p += 2; break;
-    case '3': shamt &= shamt << 5; p += 2;
-    }
-
-  if (p[0])
-    {
-      if (shfl)
-        switch (p[1])
-          {
-          case 'w': shamt &= 15; break;
-          case 'h': shamt &=  7; break;
-          case 'b': shamt &=  3; break;
-          case 'n': shamt &=  1; break;
-          default: as_fatal (_("internal error: bad permutation pseudo-instruction %s"), op);
-          }
-      else
-        switch (p[1])
-          {
-          case 'w': shamt &= 31; break;
-          case 'h': shamt &= 15; break;
-          case 'b': shamt &=  7; break;
-          case 'n': shamt &=  3; break;
-          case 'p': shamt &=  1; break;
-          default: as_fatal (_("internal error: bad permutation pseudo-instruction %s"), op);
-          }
-    }
-
-  macro_build (NULL, insn, "d,s,>", rd, rs1, shamt);
-}
-
 /* Expand RISC-V assembly macros into one or more instructions.  */
+
 static void
 macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
        bfd_reloc_code_real_type *imm_reloc)
@@ -1558,8 +1494,6 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
   int rd = (ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD;
   int rs1 = (ip->insn_opcode >> OP_SH_RS1) & OP_MASK_RS1;
   int rs2 = (ip->insn_opcode >> OP_SH_RS2) & OP_MASK_RS2;
-  int rs3 = (ip->insn_opcode >> OP_SH_RS3) & OP_MASK_RS3;
-  int shamt = (ip->insn_opcode >> OP_SH_SHAMT) & OP_MASK_SHAMT;
   int mask = ip->insn_mo->mask;
 
   switch (mask)
@@ -1568,10 +1502,6 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
       load_const (rd, imm_expr);
       break;
 
-    case M_PERM:
-      perm (rd, rs1, ip->insn_mo->name);
-      break;
-
     case M_LA:
     case M_LLA:
       /* Load the address of a symbol into a register.  */
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-32.d b/gas/testsuite/gas/riscv/bitmanip-insns-32.d
index df691cc..ff1434c 100644
--- a/gas/testsuite/gas/riscv/bitmanip-insns-32.d
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-32.d
@@ -1,6 +1,6 @@
 #as: -march=rv32ib_zbr_zbt
 #source: bitmanip-insns.s
-#objdump: -dr
+#objdump: -dr -Mno-aliases
 
 .*:[ 	]+file format .*
 
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-64.d b/gas/testsuite/gas/riscv/bitmanip-insns-64.d
index e4cf67c..f097d87 100644
--- a/gas/testsuite/gas/riscv/bitmanip-insns-64.d
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-64.d
@@ -1,6 +1,6 @@
 #as: -march=rv64ib_zbr_zbt -defsym __64_bit__=1
 #source: bitmanip-insns.s
-#objdump: -dr
+#objdump: -dr -Mno-aliases
 
 .*:[ 	]+file format .*
 
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d
index f9e7b8b..b0cdb16 100644
--- a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d
@@ -9,53 +9,53 @@ Disassembly of section .text:
 
 0+000 <.text>:
 [ 	]+[0-9a-f]+:[ 	]+0805c533[ 	]+zext.h[ 	]+a0,a1
-[ 	]+[0-9a-f]+:[ 	]+6815d513[ 	]+grevi[ 	]+a0,a1,0x1
-[ 	]+[0-9a-f]+:[ 	]+6825d513[ 	]+grevi[ 	]+a0,a1,0x2
-[ 	]+[0-9a-f]+:[ 	]+6835d513[ 	]+grevi[ 	]+a0,a1,0x3
-[ 	]+[0-9a-f]+:[ 	]+6845d513[ 	]+grevi[ 	]+a0,a1,0x4
-[ 	]+[0-9a-f]+:[ 	]+6865d513[ 	]+grevi[ 	]+a0,a1,0x6
-[ 	]+[0-9a-f]+:[ 	]+6875d513[ 	]+grevi[ 	]+a0,a1,0x7
-[ 	]+[0-9a-f]+:[ 	]+6885d513[ 	]+grevi[ 	]+a0,a1,0x8
-[ 	]+[0-9a-f]+:[ 	]+68c5d513[ 	]+grevi[ 	]+a0,a1,0xc
-[ 	]+[0-9a-f]+:[ 	]+68e5d513[ 	]+grevi[ 	]+a0,a1,0xe
-[ 	]+[0-9a-f]+:[ 	]+68f5d513[ 	]+grevi[ 	]+a0,a1,0xf
-[ 	]+[0-9a-f]+:[ 	]+6905d513[ 	]+grevi[ 	]+a0,a1,0x10
-[ 	]+[0-9a-f]+:[ 	]+6985d513[ 	]+grevi[ 	]+a0,a1,0x18
-[ 	]+[0-9a-f]+:[ 	]+69c5d513[ 	]+grevi[ 	]+a0,a1,0x1c
-[ 	]+[0-9a-f]+:[ 	]+69e5d513[ 	]+grevi[ 	]+a0,a1,0x1e
-[ 	]+[0-9a-f]+:[ 	]+69f5d513[ 	]+grevi[ 	]+a0,a1,0x1f
-[ 	]+[0-9a-f]+:[ 	]+2815d513[ 	]+gorci[ 	]+a0,a1,0x1
-[ 	]+[0-9a-f]+:[ 	]+2825d513[ 	]+gorci[ 	]+a0,a1,0x2
-[ 	]+[0-9a-f]+:[ 	]+2835d513[ 	]+gorci[ 	]+a0,a1,0x3
-[ 	]+[0-9a-f]+:[ 	]+2845d513[ 	]+gorci[ 	]+a0,a1,0x4
-[ 	]+[0-9a-f]+:[ 	]+2865d513[ 	]+gorci[ 	]+a0,a1,0x6
-[ 	]+[0-9a-f]+:[ 	]+2875d513[ 	]+gorci[ 	]+a0,a1,0x7
-[ 	]+[0-9a-f]+:[ 	]+2885d513[ 	]+gorci[ 	]+a0,a1,0x8
-[ 	]+[0-9a-f]+:[ 	]+28c5d513[ 	]+gorci[ 	]+a0,a1,0xc
-[ 	]+[0-9a-f]+:[ 	]+28e5d513[ 	]+gorci[ 	]+a0,a1,0xe
-[ 	]+[0-9a-f]+:[ 	]+28f5d513[ 	]+gorci[ 	]+a0,a1,0xf
-[ 	]+[0-9a-f]+:[ 	]+2905d513[ 	]+gorci[ 	]+a0,a1,0x10
-[ 	]+[0-9a-f]+:[ 	]+2985d513[ 	]+gorci[ 	]+a0,a1,0x18
-[ 	]+[0-9a-f]+:[ 	]+29c5d513[ 	]+gorci[ 	]+a0,a1,0x1c
-[ 	]+[0-9a-f]+:[ 	]+29e5d513[ 	]+gorci[ 	]+a0,a1,0x1e
-[ 	]+[0-9a-f]+:[ 	]+29f5d513[ 	]+gorci[ 	]+a0,a1,0x1f
-[ 	]+[0-9a-f]+:[ 	]+08159513[ 	]+shfli[ 	]+a0,a1,0x1
-[ 	]+[0-9a-f]+:[ 	]+08259513[ 	]+shfli[ 	]+a0,a1,0x2
-[ 	]+[0-9a-f]+:[ 	]+08359513[ 	]+shfli[ 	]+a0,a1,0x3
-[ 	]+[0-9a-f]+:[ 	]+08459513[ 	]+shfli[ 	]+a0,a1,0x4
-[ 	]+[0-9a-f]+:[ 	]+08659513[ 	]+shfli[ 	]+a0,a1,0x6
-[ 	]+[0-9a-f]+:[ 	]+08759513[ 	]+shfli[ 	]+a0,a1,0x7
-[ 	]+[0-9a-f]+:[ 	]+08859513[ 	]+shfli[ 	]+a0,a1,0x8
-[ 	]+[0-9a-f]+:[ 	]+08c59513[ 	]+shfli[ 	]+a0,a1,0xc
-[ 	]+[0-9a-f]+:[ 	]+08e59513[ 	]+shfli[ 	]+a0,a1,0xe
-[ 	]+[0-9a-f]+:[ 	]+08f59513[ 	]+shfli[ 	]+a0,a1,0xf
-[ 	]+[0-9a-f]+:[ 	]+0815d513[ 	]+unshfli[ 	]+a0,a1,0x1
-[ 	]+[0-9a-f]+:[ 	]+0825d513[ 	]+unshfli[ 	]+a0,a1,0x2
-[ 	]+[0-9a-f]+:[ 	]+0835d513[ 	]+unshfli[ 	]+a0,a1,0x3
-[ 	]+[0-9a-f]+:[ 	]+0845d513[ 	]+unshfli[ 	]+a0,a1,0x4
-[ 	]+[0-9a-f]+:[ 	]+0865d513[ 	]+unshfli[ 	]+a0,a1,0x6
-[ 	]+[0-9a-f]+:[ 	]+0875d513[ 	]+unshfli[ 	]+a0,a1,0x7
-[ 	]+[0-9a-f]+:[ 	]+0885d513[ 	]+unshfli[ 	]+a0,a1,0x8
-[ 	]+[0-9a-f]+:[ 	]+08c5d513[ 	]+unshfli[ 	]+a0,a1,0xc
-[ 	]+[0-9a-f]+:[ 	]+08e5d513[ 	]+unshfli[ 	]+a0,a1,0xe
-[ 	]+[0-9a-f]+:[ 	]+08f5d513[ 	]+unshfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+6815d513[ 	]+rev.p[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6825d513[ 	]+rev2.n[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6835d513[ 	]+rev.n[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6845d513[ 	]+rev4.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6865d513[ 	]+rev2.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6875d513[ 	]+rev.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6885d513[ 	]+rev8.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+68c5d513[ 	]+rev4.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+68e5d513[ 	]+rev2.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+68f5d513[ 	]+rev.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6905d513[ 	]+rev16[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6985d513[ 	]+rev8[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+69c5d513[ 	]+rev4[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+69e5d513[ 	]+rev2[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+69f5d513[ 	]+rev[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2815d513[ 	]+orc.p[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2825d513[ 	]+orc2.n[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2835d513[ 	]+orc.n[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2845d513[ 	]+orc4.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2865d513[ 	]+orc2.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2875d513[ 	]+orc.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2885d513[ 	]+orc8.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+28c5d513[ 	]+orc4.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+28e5d513[ 	]+orc2.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+28f5d513[ 	]+orc.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2905d513[ 	]+orc16[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2985d513[ 	]+orc8[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+29c5d513[ 	]+orc4[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+29e5d513[ 	]+orc2[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+29f5d513[ 	]+orc[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08159513[ 	]+zip.n[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08259513[ 	]+zip2.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08359513[ 	]+zip.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08459513[ 	]+zip4.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08659513[ 	]+zip2.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08759513[ 	]+zip.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08859513[ 	]+zip8[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08c59513[ 	]+zip4[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08e59513[ 	]+zip2[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08f59513[ 	]+zip[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0815d513[ 	]+unzip.n[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0825d513[ 	]+unzip2.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0835d513[ 	]+unzip.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0845d513[ 	]+unzip4.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0865d513[ 	]+unzip2.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0875d513[ 	]+unzip.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0885d513[ 	]+unzip8[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08c5d513[ 	]+unzip4[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08e5d513[ 	]+unzip2[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08f5d513[ 	]+unzip[ 	]+a0,a1
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d
index 0c25bae..23b8b7b 100644
--- a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d
@@ -9,76 +9,76 @@ Disassembly of section .text:
 
 0+000 <.text>:
 [ 	]+[0-9a-f]+:[ 	]+0805c53b[ 	]+zext.h[ 	]+a0,a1
-[ 	]+[0-9a-f]+:[ 	]+6815d513[ 	]+grevi[ 	]+a0,a1,0x1
-[ 	]+[0-9a-f]+:[ 	]+6825d513[ 	]+grevi[ 	]+a0,a1,0x2
-[ 	]+[0-9a-f]+:[ 	]+6835d513[ 	]+grevi[ 	]+a0,a1,0x3
-[ 	]+[0-9a-f]+:[ 	]+6845d513[ 	]+grevi[ 	]+a0,a1,0x4
-[ 	]+[0-9a-f]+:[ 	]+6865d513[ 	]+grevi[ 	]+a0,a1,0x6
-[ 	]+[0-9a-f]+:[ 	]+6875d513[ 	]+grevi[ 	]+a0,a1,0x7
-[ 	]+[0-9a-f]+:[ 	]+6885d513[ 	]+grevi[ 	]+a0,a1,0x8
-[ 	]+[0-9a-f]+:[ 	]+68c5d513[ 	]+grevi[ 	]+a0,a1,0xc
-[ 	]+[0-9a-f]+:[ 	]+68e5d513[ 	]+grevi[ 	]+a0,a1,0xe
-[ 	]+[0-9a-f]+:[ 	]+68f5d513[ 	]+grevi[ 	]+a0,a1,0xf
-[ 	]+[0-9a-f]+:[ 	]+6b05d513[ 	]+grevi[ 	]+a0,a1,0x30
-[ 	]+[0-9a-f]+:[ 	]+6b85d513[ 	]+grevi[ 	]+a0,a1,0x38
-[ 	]+[0-9a-f]+:[ 	]+6bc5d513[ 	]+grevi[ 	]+a0,a1,0x3c
-[ 	]+[0-9a-f]+:[ 	]+6be5d513[ 	]+grevi[ 	]+a0,a1,0x3e
-[ 	]+[0-9a-f]+:[ 	]+6bf5d513[ 	]+grevi[ 	]+a0,a1,0x3f
-[ 	]+[0-9a-f]+:[ 	]+2815d513[ 	]+gorci[ 	]+a0,a1,0x1
-[ 	]+[0-9a-f]+:[ 	]+2825d513[ 	]+gorci[ 	]+a0,a1,0x2
-[ 	]+[0-9a-f]+:[ 	]+2835d513[ 	]+gorci[ 	]+a0,a1,0x3
-[ 	]+[0-9a-f]+:[ 	]+2845d513[ 	]+gorci[ 	]+a0,a1,0x4
-[ 	]+[0-9a-f]+:[ 	]+2865d513[ 	]+gorci[ 	]+a0,a1,0x6
-[ 	]+[0-9a-f]+:[ 	]+2875d513[ 	]+gorci[ 	]+a0,a1,0x7
-[ 	]+[0-9a-f]+:[ 	]+2885d513[ 	]+gorci[ 	]+a0,a1,0x8
-[ 	]+[0-9a-f]+:[ 	]+28c5d513[ 	]+gorci[ 	]+a0,a1,0xc
-[ 	]+[0-9a-f]+:[ 	]+28e5d513[ 	]+gorci[ 	]+a0,a1,0xe
-[ 	]+[0-9a-f]+:[ 	]+28f5d513[ 	]+gorci[ 	]+a0,a1,0xf
-[ 	]+[0-9a-f]+:[ 	]+2b05d513[ 	]+gorci[ 	]+a0,a1,0x30
-[ 	]+[0-9a-f]+:[ 	]+2b85d513[ 	]+gorci[ 	]+a0,a1,0x38
-[ 	]+[0-9a-f]+:[ 	]+2bc5d513[ 	]+gorci[ 	]+a0,a1,0x3c
-[ 	]+[0-9a-f]+:[ 	]+2be5d513[ 	]+gorci[ 	]+a0,a1,0x3e
-[ 	]+[0-9a-f]+:[ 	]+2bf5d513[ 	]+gorci[ 	]+a0,a1,0x3f
-[ 	]+[0-9a-f]+:[ 	]+08159513[ 	]+shfli[ 	]+a0,a1,0x1
-[ 	]+[0-9a-f]+:[ 	]+08259513[ 	]+shfli[ 	]+a0,a1,0x2
-[ 	]+[0-9a-f]+:[ 	]+08359513[ 	]+shfli[ 	]+a0,a1,0x3
-[ 	]+[0-9a-f]+:[ 	]+08459513[ 	]+shfli[ 	]+a0,a1,0x4
-[ 	]+[0-9a-f]+:[ 	]+08659513[ 	]+shfli[ 	]+a0,a1,0x6
-[ 	]+[0-9a-f]+:[ 	]+08759513[ 	]+shfli[ 	]+a0,a1,0x7
-[ 	]+[0-9a-f]+:[ 	]+09859513[ 	]+shfli[ 	]+a0,a1,0x18
-[ 	]+[0-9a-f]+:[ 	]+09c59513[ 	]+shfli[ 	]+a0,a1,0x1c
-[ 	]+[0-9a-f]+:[ 	]+09e59513[ 	]+shfli[ 	]+a0,a1,0x1e
-[ 	]+[0-9a-f]+:[ 	]+09f59513[ 	]+shfli[ 	]+a0,a1,0x1f
-[ 	]+[0-9a-f]+:[ 	]+0815d513[ 	]+unshfli[ 	]+a0,a1,0x1
-[ 	]+[0-9a-f]+:[ 	]+0825d513[ 	]+unshfli[ 	]+a0,a1,0x2
-[ 	]+[0-9a-f]+:[ 	]+0835d513[ 	]+unshfli[ 	]+a0,a1,0x3
-[ 	]+[0-9a-f]+:[ 	]+0845d513[ 	]+unshfli[ 	]+a0,a1,0x4
-[ 	]+[0-9a-f]+:[ 	]+0865d513[ 	]+unshfli[ 	]+a0,a1,0x6
-[ 	]+[0-9a-f]+:[ 	]+0875d513[ 	]+unshfli[ 	]+a0,a1,0x7
-[ 	]+[0-9a-f]+:[ 	]+0985d513[ 	]+unshfli[ 	]+a0,a1,0x18
-[ 	]+[0-9a-f]+:[ 	]+09c5d513[ 	]+unshfli[ 	]+a0,a1,0x1c
-[ 	]+[0-9a-f]+:[ 	]+09e5d513[ 	]+unshfli[ 	]+a0,a1,0x1e
-[ 	]+[0-9a-f]+:[ 	]+09f5d513[ 	]+unshfli[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+6815d513[ 	]+rev.p[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6825d513[ 	]+rev2.n[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6835d513[ 	]+rev.n[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6845d513[ 	]+rev4.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6865d513[ 	]+rev2.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6875d513[ 	]+rev.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6885d513[ 	]+rev8.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+68c5d513[ 	]+rev4.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+68e5d513[ 	]+rev2.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+68f5d513[ 	]+rev.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6b05d513[ 	]+rev16[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6b85d513[ 	]+rev8[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6bc5d513[ 	]+rev4[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6be5d513[ 	]+rev2[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6bf5d513[ 	]+rev[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2815d513[ 	]+orc.p[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2825d513[ 	]+orc2.n[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2835d513[ 	]+orc.n[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2845d513[ 	]+orc4.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2865d513[ 	]+orc2.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2875d513[ 	]+orc.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2885d513[ 	]+orc8.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+28c5d513[ 	]+orc4.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+28e5d513[ 	]+orc2.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+28f5d513[ 	]+orc.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2b05d513[ 	]+orc16[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2b85d513[ 	]+orc8[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2bc5d513[ 	]+orc4[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2be5d513[ 	]+orc2[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2bf5d513[ 	]+orc[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08159513[ 	]+zip.n[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08259513[ 	]+zip2.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08359513[ 	]+zip.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08459513[ 	]+zip4.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08659513[ 	]+zip2.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08759513[ 	]+zip.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+09859513[ 	]+zip8[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+09c59513[ 	]+zip4[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+09e59513[ 	]+zip2[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+09f59513[ 	]+zip[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0815d513[ 	]+unzip.n[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0825d513[ 	]+unzip2.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0835d513[ 	]+unzip.b[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0845d513[ 	]+unzip4.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0865d513[ 	]+unzip2.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0875d513[ 	]+unzip.h[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0985d513[ 	]+unzip8[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+09c5d513[ 	]+unzip4[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+09e5d513[ 	]+unzip2[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+09f5d513[ 	]+unzip[ 	]+a0,a1
 [ 	]+[0-9a-f]+:[ 	]+0805853b[ 	]+zext.w[ 	]+a0,a1
-[ 	]+[0-9a-f]+:[ 	]+6905d513[ 	]+grevi[ 	]+a0,a1,0x10
-[ 	]+[0-9a-f]+:[ 	]+6985d513[ 	]+grevi[ 	]+a0,a1,0x18
-[ 	]+[0-9a-f]+:[ 	]+69c5d513[ 	]+grevi[ 	]+a0,a1,0x1c
-[ 	]+[0-9a-f]+:[ 	]+69e5d513[ 	]+grevi[ 	]+a0,a1,0x1e
-[ 	]+[0-9a-f]+:[ 	]+69f5d513[ 	]+grevi[ 	]+a0,a1,0x1f
-[ 	]+[0-9a-f]+:[ 	]+6a05d513[ 	]+grevi[ 	]+a0,a1,0x20
-[ 	]+[0-9a-f]+:[ 	]+2905d513[ 	]+gorci[ 	]+a0,a1,0x10
-[ 	]+[0-9a-f]+:[ 	]+2985d513[ 	]+gorci[ 	]+a0,a1,0x18
-[ 	]+[0-9a-f]+:[ 	]+29c5d513[ 	]+gorci[ 	]+a0,a1,0x1c
-[ 	]+[0-9a-f]+:[ 	]+29e5d513[ 	]+gorci[ 	]+a0,a1,0x1e
-[ 	]+[0-9a-f]+:[ 	]+29f5d513[ 	]+gorci[ 	]+a0,a1,0x1f
-[ 	]+[0-9a-f]+:[ 	]+2a05d513[ 	]+gorci[ 	]+a0,a1,0x20
-[ 	]+[0-9a-f]+:[ 	]+08859513[ 	]+shfli[ 	]+a0,a1,0x8
-[ 	]+[0-9a-f]+:[ 	]+08c59513[ 	]+shfli[ 	]+a0,a1,0xc
-[ 	]+[0-9a-f]+:[ 	]+08e59513[ 	]+shfli[ 	]+a0,a1,0xe
-[ 	]+[0-9a-f]+:[ 	]+08f59513[ 	]+shfli[ 	]+a0,a1,0xf
-[ 	]+[0-9a-f]+:[ 	]+09059513[ 	]+shfli[ 	]+a0,a1,0x10
-[ 	]+[0-9a-f]+:[ 	]+0885d513[ 	]+unshfli[ 	]+a0,a1,0x8
-[ 	]+[0-9a-f]+:[ 	]+08c5d513[ 	]+unshfli[ 	]+a0,a1,0xc
-[ 	]+[0-9a-f]+:[ 	]+08e5d513[ 	]+unshfli[ 	]+a0,a1,0xe
-[ 	]+[0-9a-f]+:[ 	]+08f5d513[ 	]+unshfli[ 	]+a0,a1,0xf
-[ 	]+[0-9a-f]+:[ 	]+0905d513[ 	]+unshfli[ 	]+a0,a1,0x10
+[ 	]+[0-9a-f]+:[ 	]+6905d513[ 	]+rev16.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6985d513[ 	]+rev8.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+69c5d513[ 	]+rev4.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+69e5d513[ 	]+rev2.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+69f5d513[ 	]+rev.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+6a05d513[ 	]+rev32[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2905d513[ 	]+orc16.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2985d513[ 	]+orc8.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+29c5d513[ 	]+orc4.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+29e5d513[ 	]+orc2.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+29f5d513[ 	]+orc.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+2a05d513[ 	]+orc32[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08859513[ 	]+zip8.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08c59513[ 	]+zip4.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08e59513[ 	]+zip2.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08f59513[ 	]+zip.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+09059513[ 	]+zip16[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0885d513[ 	]+unzip8.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08c5d513[ 	]+unzip4.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08e5d513[ 	]+unzip2.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+08f5d513[ 	]+unzip.w[ 	]+a0,a1
+[ 	]+[0-9a-f]+:[ 	]+0905d513[ 	]+unzip16[ 	]+a0,a1
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-32.d b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-32.d
new file mode 100644
index 0000000..91190c8
--- /dev/null
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-32.d
@@ -0,0 +1,61 @@
+#as: -march=rv32ib
+#source: bitmanip-insns-pseudo.s
+#objdump: -dr -Mno-aliases
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ 	]+[0-9a-f]+:[ 	]+0805c533[ 	]+pack[ 	]+a0,a1,zero
+[ 	]+[0-9a-f]+:[ 	]+6815d513[ 	]+grevi[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+6825d513[ 	]+grevi[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+6835d513[ 	]+grevi[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+6845d513[ 	]+grevi[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+6865d513[ 	]+grevi[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+6875d513[ 	]+grevi[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+6885d513[ 	]+grevi[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+68c5d513[ 	]+grevi[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+68e5d513[ 	]+grevi[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+68f5d513[ 	]+grevi[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+6905d513[ 	]+grevi[ 	]+a0,a1,0x10
+[ 	]+[0-9a-f]+:[ 	]+6985d513[ 	]+grevi[ 	]+a0,a1,0x18
+[ 	]+[0-9a-f]+:[ 	]+69c5d513[ 	]+grevi[ 	]+a0,a1,0x1c
+[ 	]+[0-9a-f]+:[ 	]+69e5d513[ 	]+grevi[ 	]+a0,a1,0x1e
+[ 	]+[0-9a-f]+:[ 	]+69f5d513[ 	]+grevi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+2815d513[ 	]+gorci[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+2825d513[ 	]+gorci[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+2835d513[ 	]+gorci[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+2845d513[ 	]+gorci[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+2865d513[ 	]+gorci[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+2875d513[ 	]+gorci[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+2885d513[ 	]+gorci[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+28c5d513[ 	]+gorci[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+28e5d513[ 	]+gorci[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+28f5d513[ 	]+gorci[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+2905d513[ 	]+gorci[ 	]+a0,a1,0x10
+[ 	]+[0-9a-f]+:[ 	]+2985d513[ 	]+gorci[ 	]+a0,a1,0x18
+[ 	]+[0-9a-f]+:[ 	]+29c5d513[ 	]+gorci[ 	]+a0,a1,0x1c
+[ 	]+[0-9a-f]+:[ 	]+29e5d513[ 	]+gorci[ 	]+a0,a1,0x1e
+[ 	]+[0-9a-f]+:[ 	]+29f5d513[ 	]+gorci[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+08159513[ 	]+shfli[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+08259513[ 	]+shfli[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+08359513[ 	]+shfli[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+08459513[ 	]+shfli[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+08659513[ 	]+shfli[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+08759513[ 	]+shfli[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+08859513[ 	]+shfli[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+08c59513[ 	]+shfli[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+08e59513[ 	]+shfli[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+08f59513[ 	]+shfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+0815d513[ 	]+unshfli[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+0825d513[ 	]+unshfli[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+0835d513[ 	]+unshfli[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+0845d513[ 	]+unshfli[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+0865d513[ 	]+unshfli[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+0875d513[ 	]+unshfli[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+0885d513[ 	]+unshfli[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+08c5d513[ 	]+unshfli[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+08e5d513[ 	]+unshfli[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+08f5d513[ 	]+unshfli[ 	]+a0,a1,0xf
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-64.d b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-64.d
new file mode 100644
index 0000000..187c487
--- /dev/null
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-64.d
@@ -0,0 +1,84 @@
+#as: -march=rv64ib -defsym __64_bit__=1
+#source: bitmanip-insns-pseudo.s
+#objdump: -dr -Mno-aliases
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ 	]+[0-9a-f]+:[ 	]+0805c53b[ 	]+packw[ 	]+a0,a1,zero
+[ 	]+[0-9a-f]+:[ 	]+6815d513[ 	]+grevi[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+6825d513[ 	]+grevi[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+6835d513[ 	]+grevi[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+6845d513[ 	]+grevi[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+6865d513[ 	]+grevi[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+6875d513[ 	]+grevi[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+6885d513[ 	]+grevi[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+68c5d513[ 	]+grevi[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+68e5d513[ 	]+grevi[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+68f5d513[ 	]+grevi[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+6b05d513[ 	]+grevi[ 	]+a0,a1,0x30
+[ 	]+[0-9a-f]+:[ 	]+6b85d513[ 	]+grevi[ 	]+a0,a1,0x38
+[ 	]+[0-9a-f]+:[ 	]+6bc5d513[ 	]+grevi[ 	]+a0,a1,0x3c
+[ 	]+[0-9a-f]+:[ 	]+6be5d513[ 	]+grevi[ 	]+a0,a1,0x3e
+[ 	]+[0-9a-f]+:[ 	]+6bf5d513[ 	]+grevi[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+2815d513[ 	]+gorci[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+2825d513[ 	]+gorci[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+2835d513[ 	]+gorci[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+2845d513[ 	]+gorci[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+2865d513[ 	]+gorci[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+2875d513[ 	]+gorci[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+2885d513[ 	]+gorci[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+28c5d513[ 	]+gorci[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+28e5d513[ 	]+gorci[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+28f5d513[ 	]+gorci[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+2b05d513[ 	]+gorci[ 	]+a0,a1,0x30
+[ 	]+[0-9a-f]+:[ 	]+2b85d513[ 	]+gorci[ 	]+a0,a1,0x38
+[ 	]+[0-9a-f]+:[ 	]+2bc5d513[ 	]+gorci[ 	]+a0,a1,0x3c
+[ 	]+[0-9a-f]+:[ 	]+2be5d513[ 	]+gorci[ 	]+a0,a1,0x3e
+[ 	]+[0-9a-f]+:[ 	]+2bf5d513[ 	]+gorci[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+08159513[ 	]+shfli[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+08259513[ 	]+shfli[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+08359513[ 	]+shfli[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+08459513[ 	]+shfli[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+08659513[ 	]+shfli[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+08759513[ 	]+shfli[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+09859513[ 	]+shfli[ 	]+a0,a1,0x18
+[ 	]+[0-9a-f]+:[ 	]+09c59513[ 	]+shfli[ 	]+a0,a1,0x1c
+[ 	]+[0-9a-f]+:[ 	]+09e59513[ 	]+shfli[ 	]+a0,a1,0x1e
+[ 	]+[0-9a-f]+:[ 	]+09f59513[ 	]+shfli[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+0815d513[ 	]+unshfli[ 	]+a0,a1,0x1
+[ 	]+[0-9a-f]+:[ 	]+0825d513[ 	]+unshfli[ 	]+a0,a1,0x2
+[ 	]+[0-9a-f]+:[ 	]+0835d513[ 	]+unshfli[ 	]+a0,a1,0x3
+[ 	]+[0-9a-f]+:[ 	]+0845d513[ 	]+unshfli[ 	]+a0,a1,0x4
+[ 	]+[0-9a-f]+:[ 	]+0865d513[ 	]+unshfli[ 	]+a0,a1,0x6
+[ 	]+[0-9a-f]+:[ 	]+0875d513[ 	]+unshfli[ 	]+a0,a1,0x7
+[ 	]+[0-9a-f]+:[ 	]+0985d513[ 	]+unshfli[ 	]+a0,a1,0x18
+[ 	]+[0-9a-f]+:[ 	]+09c5d513[ 	]+unshfli[ 	]+a0,a1,0x1c
+[ 	]+[0-9a-f]+:[ 	]+09e5d513[ 	]+unshfli[ 	]+a0,a1,0x1e
+[ 	]+[0-9a-f]+:[ 	]+09f5d513[ 	]+unshfli[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+0805853b[ 	]+addu.w[ 	]+a0,a1,zero
+[ 	]+[0-9a-f]+:[ 	]+6905d513[ 	]+grevi[ 	]+a0,a1,0x10
+[ 	]+[0-9a-f]+:[ 	]+6985d513[ 	]+grevi[ 	]+a0,a1,0x18
+[ 	]+[0-9a-f]+:[ 	]+69c5d513[ 	]+grevi[ 	]+a0,a1,0x1c
+[ 	]+[0-9a-f]+:[ 	]+69e5d513[ 	]+grevi[ 	]+a0,a1,0x1e
+[ 	]+[0-9a-f]+:[ 	]+69f5d513[ 	]+grevi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+6a05d513[ 	]+grevi[ 	]+a0,a1,0x20
+[ 	]+[0-9a-f]+:[ 	]+2905d513[ 	]+gorci[ 	]+a0,a1,0x10
+[ 	]+[0-9a-f]+:[ 	]+2985d513[ 	]+gorci[ 	]+a0,a1,0x18
+[ 	]+[0-9a-f]+:[ 	]+29c5d513[ 	]+gorci[ 	]+a0,a1,0x1c
+[ 	]+[0-9a-f]+:[ 	]+29e5d513[ 	]+gorci[ 	]+a0,a1,0x1e
+[ 	]+[0-9a-f]+:[ 	]+29f5d513[ 	]+gorci[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+2a05d513[ 	]+gorci[ 	]+a0,a1,0x20
+[ 	]+[0-9a-f]+:[ 	]+08859513[ 	]+shfli[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+08c59513[ 	]+shfli[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+08e59513[ 	]+shfli[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+08f59513[ 	]+shfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+09059513[ 	]+shfli[ 	]+a0,a1,0x10
+[ 	]+[0-9a-f]+:[ 	]+0885d513[ 	]+unshfli[ 	]+a0,a1,0x8
+[ 	]+[0-9a-f]+:[ 	]+08c5d513[ 	]+unshfli[ 	]+a0,a1,0xc
+[ 	]+[0-9a-f]+:[ 	]+08e5d513[ 	]+unshfli[ 	]+a0,a1,0xe
+[ 	]+[0-9a-f]+:[ 	]+08f5d513[ 	]+unshfli[ 	]+a0,a1,0xf
+[ 	]+[0-9a-f]+:[ 	]+0905d513[ 	]+unshfli[ 	]+a0,a1,0x10
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 0255feb..25c9ce7 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -498,7 +498,6 @@ enum
   M_ZEXTW,
   M_SEXTB,
   M_SEXTH,
-  M_PERM,
   M_NUM_MACROS
 };
 
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index bf8b27a..4bc66ca 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -56,6 +56,51 @@ const char * const riscv_fpr_names_abi[NFPR] = {
   "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11"
 };
 
+/* The MATCH/MASK immediate macros for rvb pseudo instructions.  */
+
+#define MASK_RVB_IMM (OP_MASK_SHAMT << OP_SH_SHAMT)
+
+#define ENCODE_PERM_IMM(xlen, prefix, suffix) \
+  (ENCODE_ITYPE_IMM ((((xlen) - 1) & (((xlen) - 1) << (prefix)) & (suffix))))
+
+#define MATCH_PERM_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 0, -1))
+#define MATCH_PERM2_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 1, -1))
+#define MATCH_PERM4_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 2, -1))
+#define MATCH_PERM8_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 3, -1))
+#define MATCH_PERM16_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 4, -1))
+#define MATCH_PERM32_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 5, -1))
+#define MATCH_PERMP_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 0, 0x1))
+#define MATCH_PERMN_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 0, 0x3))
+#define MATCH_PERMB_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 0, 0x7))
+#define MATCH_PERMH_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 0, 0xf))
+#define MATCH_PERMW_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 0, 0x1f))
+#define MATCH_PERM2N_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 1, 0x3))
+#define MATCH_PERM2B_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 1, 0x7))
+#define MATCH_PERM4B_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 2, 0x7))
+#define MATCH_PERM2H_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 1, 0xf))
+#define MATCH_PERM4H_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 2, 0xf))
+#define MATCH_PERM8H_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 3, 0xf))
+#define MATCH_PERM2W_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 1, 0x1f))
+#define MATCH_PERM4W_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 2, 0x1f))
+#define MATCH_PERM8W_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 3, 0x1f))
+#define MATCH_PERM16W_IMM(xlen)	(ENCODE_PERM_IMM ((xlen), 4, 0x1f))
+
+#define MATCH_PERM_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 0, -1))
+#define MATCH_PERM2_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 1, -1))
+#define MATCH_PERM4_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 2, -1))
+#define MATCH_PERM8_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 3, -1))
+#define MATCH_PERM16_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 4, -1))
+#define MATCH_PERMN_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 0, 0x1))
+#define MATCH_PERMB_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 0, 0x3))
+#define MATCH_PERMH_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 0, 0x7))
+#define MATCH_PERMW_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 0, 0xf))
+#define MATCH_PERM2B_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 1, 0x3))
+#define MATCH_PERM2H_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 1, 0x7))
+#define MATCH_PERM4H_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 2, 0x7))
+#define MATCH_PERM2W_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 1, 0xf))
+#define MATCH_PERM4W_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 2, 0xf))
+#define MATCH_PERM8W_SHFL_IMM(xlen)	(ENCODE_PERM_IMM ((xlen/2), 3, 0xf))
+
 /* The order of overloaded instructions matters.  Label arguments and
    register arguments look the same. Instructions that can have either
    for arguments must apear in the correct order in this table for the
@@ -498,6 +543,133 @@ const struct riscv_opcode riscv_opcodes[] =
 {"remw",     64, INSN_CLASS_M, "d,s,t",  MATCH_REMW, MASK_REMW, match_opcode, 0 },
 {"remuw",    64, INSN_CLASS_M, "d,s,t",  MATCH_REMUW, MASK_REMUW, match_opcode, 0 },
 
+/* Bitmanip pseudo-instructions  */
+{"rev.p",    32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERMP_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev.p",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERMP_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev2.n",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM2N_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev2.n",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM2N_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev.n",    32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERMN_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev.n",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERMN_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev4.b",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM4B_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev4.b",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM4B_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev2.b",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM2B_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev2.b",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM2B_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev.b",    32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERMB_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev.b",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERMB_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev8.h",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM8H_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev8.h",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM8H_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev4.h",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM4H_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev4.h",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM4H_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev2.h",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM2H_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev2.h",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM2H_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev.h",    32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERMH_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev.h",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERMH_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev16",    32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM16_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev16",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM16_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev8",     32, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM8_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev8",     64, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM8_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev4",     32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM4_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev4",     64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM4_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev2",     32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM2_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev2",     64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM2_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev",      32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM_IMM (32), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev",      64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev16.w",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM16W_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev8.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM8W_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev4.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM4W_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev2.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM2W_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev.w",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERMW_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"rev32",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GREVI | MATCH_PERM32_IMM (64), MASK_GREVI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+
+{"orc.p",    32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERMP_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc.p",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERMP_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc2.n",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM2N_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc2.n",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM2N_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc.n",    32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERMN_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc.n",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERMN_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc4.b",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM4B_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc4.b",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM4B_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc2.b",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM2B_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc2.b",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM2B_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc.b",    32, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERMB_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc.b",    64, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERMB_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc8.h",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM8H_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc8.h",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM8H_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc4.h",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM4H_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc4.h",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM4H_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc2.h",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM2H_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc2.h",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM2H_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc.h",    32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERMH_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc.h",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERMH_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc16",    32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM16_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc16",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM16_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc8",     32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM8_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc8",     64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM8_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc4",     32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM4_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc4",     64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM4_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc2",     32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM2_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc2",     64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM2_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc",      32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM_IMM (32), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc",      64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc16.w",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM16W_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc8.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM8W_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc4.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM4W_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc2.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM2W_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc.w",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERMW_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"orc32",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_GORCI | MATCH_PERM32_IMM (64), MASK_GORCI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+
+{"zip.n",    32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERMN_SHFL_IMM (32), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip.n",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERMN_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip2.b",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM2B_SHFL_IMM (32), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip2.b",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM2B_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip.b",    32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERMB_SHFL_IMM (32), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip.b",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERMB_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip4.h",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM4H_SHFL_IMM (32), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip4.h",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM4H_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip2.h",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM2H_SHFL_IMM (32), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip2.h",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM2H_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip.h",    32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERMH_SHFL_IMM (32), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip.h",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERMH_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip8",     32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM8_SHFL_IMM (32), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip8",     64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM8_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip4",     32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM4_SHFL_IMM (32), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip4",     64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM4_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip2",     32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM2_SHFL_IMM (32), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip2",     64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM2_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip",      32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM_SHFL_IMM (32), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip",      64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip8.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM8W_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip4.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM4W_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip2.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM2W_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip.w",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERMW_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"zip16",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_SHFLI | MATCH_PERM16_SHFL_IMM (64), MASK_SHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+
+{"unzip.n",  32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERMN_SHFL_IMM (32), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip.n",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERMN_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip2.b", 32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM2B_SHFL_IMM (32), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip2.b", 64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM2B_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip.b",  32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERMB_SHFL_IMM (32), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip.b",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERMB_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip4.h", 32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM4H_SHFL_IMM (32), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip4.h", 64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM4H_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip2.h", 32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM2H_SHFL_IMM (32), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip2.h", 64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM2H_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip.h",  32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERMH_SHFL_IMM (32), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip.h",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERMH_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip8",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM8_SHFL_IMM (32), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip8",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM8_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip4",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM4_SHFL_IMM (32), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip4",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM4_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip2",   32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM2_SHFL_IMM (32), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip2",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM2_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip",    32, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM_SHFL_IMM (32), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip8.w", 64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM8W_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip4.w", 64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM4W_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip2.w", 64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM2W_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip.w",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERMW_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+{"unzip16",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  MATCH_UNSHFLI | MATCH_PERM16_SHFL_IMM (64), MASK_UNSHFLI | MASK_RVB_IMM, match_opcode, INSN_ALIAS },
+
 /* Bitmanip instruction subset  */
 {"sh1add",    0, INSN_CLASS_B_OR_ZBA,   "d,s,t",  MATCH_SH1ADD, MASK_SH1ADD, match_opcode, 0 },
 {"sh2add",    0, INSN_CLASS_B_OR_ZBA,   "d,s,t",  MATCH_SH2ADD, MASK_SH2ADD, match_opcode, 0 },
@@ -628,83 +800,6 @@ const struct riscv_opcode riscv_opcodes[] =
 {"fsrw",     64, INSN_CLASS_ZBT,   "d,s,r,t",  MATCH_FSRW, MASK_FSRW, match_opcode, 0 },
 {"fsrw",     64, INSN_CLASS_ZBT,   "d,s,r,<",  MATCH_FSRIW, MASK_FSRIW, match_opcode, INSN_ALIAS },
 
-/* Bitmanip pseudo-instructions  */
-{"rev.p",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev2.n",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev.n",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev4.b",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev2.b",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev.b",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev8.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev4.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev2.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev.h",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev16.w",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev8.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev4.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev2.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev.w",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev32",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev16",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev8",      0, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev4",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev2",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"rev",       0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-
-{"orc.p",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc2.n",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc.n",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc4.b",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc2.b",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc.b",     0, INSN_CLASS_B_OR_ZBB_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc8.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc4.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc2.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc.h",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc16.w",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc8.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc4.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc2.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc.w",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc32",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc16",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc8",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc4",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc2",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"orc",       0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-
-{"zip.n",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip2.b",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip.b",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip4.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip2.h",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip.h",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip8.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip4.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip2.w",   64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip.w",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip16",    64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip8",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip4",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip2",      0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"zip",       0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-
-{"unzip.n",   0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip2.b",  0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip.b",   0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip4.h",  0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip2.h",  0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip.h",   0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip8.w", 64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip4.w", 64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip2.w", 64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip.w",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip16",  64, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip8",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip4",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip2",    0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-{"unzip",     0, INSN_CLASS_B_OR_ZBP,   "d,s",  0, (int) M_PERM, match_never, INSN_MACRO },
-
 /* Single-precision floating-point instruction subset */
 {"frcsr",     0, INSN_CLASS_F,   "d",  MATCH_FRCSR, MASK_FRCSR, match_opcode, INSN_ALIAS },
 {"frsr",      0, INSN_CLASS_F,   "d",  MATCH_FRCSR, MASK_FRCSR, match_opcode, INSN_ALIAS },
-- 
2.7.4


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

* [PATCH 3/3] RISC-V: Add -menable-experimental-extensions option.
  2020-12-15 15:11 [PATCH 0/3] RISC-V: Add -menable-experimental-extensions and support bitmanip instructions Nelson Chu
  2020-12-15 15:11 ` [PATCH 1/3] RISC-V: Support riscv " Nelson Chu
  2020-12-15 15:11 ` [PATCH 2/3] RISC-V: Define pseudo rev/orc/zip/unzip as alias instructions Nelson Chu
@ 2020-12-15 15:11 ` Nelson Chu
  2020-12-15 18:23 ` [PATCH 0/3] RISC-V: Add -menable-experimental-extensions and support bitmanip instructions Palmer Dabbelt
  3 siblings, 0 replies; 8+ messages in thread
From: Nelson Chu @ 2020-12-15 15:11 UTC (permalink / raw)
  To: binutils, claire, maxim.blinov, jimw, andrew, palmer, kito.cheng

This is originally discussed in the following link,
https://sourceware.org/pipermail/binutils/2020-December/114439.html

bfd/
    * elfnn-riscv.c (riscv_merge_arch_attr_info): Always enable the
    experimental flag when merging arch string in linker.
    * elfxx-riscv.c (riscv_is_experimental_extension): New function.
    Return True if the extension is experimental; Otherwise, return FALSE.
    (riscv_parse_add_subset): Report error if the extension is experimental,
    but the -menable-experimental-extensions options is not set.
    * elfxx-riscv.h (riscv_parse_subset_t): Add boolean enable_experimental.
gas/
    * config/tc-riscv.c (riscv_set_options): Add enable_experimental.
    (riscv_opts): Default disallow the experimental extensions.
    (riscv_set_arch): Set rps.enable_experimental.
    (enum options): Add OPTION_ENABLE_EXPERIMENTAL.
    (md_longopts): Add --menable-experimental-extensions.
    (md_parse_option): Updated.
    * testsuite/gas/riscv/attribute-draft-b.d: Add -menable-experimental-extensions.
    * testsuite/gas/riscv/bitmanip-insns-32.d: Likewise.
    * testsuite/gas/riscv/bitmanip-insns-64.d: Likewise.
    * testsuite/gas/riscv/bitmanip-insns-pseudo-32.d: Likewise.
    * testsuite/gas/riscv/bitmanip-insns-pseudo-64.d: Likewise.
    * testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-32.d: Likewise.
    * testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-64.d: Likewise.
    * testsuite/gas/riscv/march-fail-experimental.d: New testcase.
    * testsuite/gas/riscv/march-fail-experimental.l: New testcase.
---
 bfd/elfnn-riscv.c                                   |  2 ++
 bfd/elfxx-riscv.c                                   | 19 +++++++++++++++++++
 bfd/elfxx-riscv.h                                   |  1 +
 gas/config/tc-riscv.c                               | 21 +++++++++++++++------
 gas/testsuite/gas/riscv/attribute-draft-b.d         |  2 +-
 gas/testsuite/gas/riscv/bitmanip-insns-32.d         |  2 +-
 gas/testsuite/gas/riscv/bitmanip-insns-64.d         |  2 +-
 gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d  |  2 +-
 gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d  |  2 +-
 .../gas/riscv/bitmanip-insns-pseudo-noalias-32.d    |  2 +-
 .../gas/riscv/bitmanip-insns-pseudo-noalias-64.d    |  2 +-
 gas/testsuite/gas/riscv/march-fail-experimental.d   |  3 +++
 gas/testsuite/gas/riscv/march-fail-experimental.l   | 12 ++++++++++++
 13 files changed, 59 insertions(+), 13 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/march-fail-experimental.d
 create mode 100644 gas/testsuite/gas/riscv/march-fail-experimental.l

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 20944c8..160a14d 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -3526,11 +3526,13 @@ riscv_merge_arch_attr_info (bfd *ibfd, char *in_arch, char *out_arch)
   rpe_in.error_handler = _bfd_error_handler;
   rpe_in.xlen = &xlen_in;
   rpe_in.get_default_version = NULL;
+  rpe_in.enable_experimental = TRUE;
 
   rpe_out.subset_list = &out_subsets;
   rpe_out.error_handler = _bfd_error_handler;
   rpe_out.xlen = &xlen_out;
   rpe_out.get_default_version = NULL;
+  rpe_in.enable_experimental = TRUE;
 
   if (in_arch == NULL && out_arch == NULL)
     return NULL;
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 016905d..1b7c2da 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1163,6 +1163,16 @@ riscv_ext_dont_care_version (const char *subset)
   return FALSE;
 }
 
+static bfd_boolean
+riscv_is_experimental_extension (const char *subset)
+{
+  if (riscv_get_prefix_class (subset) == RV_ISA_CLASS_Z)
+    subset++;
+  if (subset[0] == 'b')
+    return TRUE;
+  return FALSE;
+}
+
 /* We have to add all arch string extensions first, and then start to
    add their implicit extensions.  The arch string extensions must be
    set in order, so we can add them to the last of the subset list
@@ -1182,6 +1192,15 @@ riscv_parse_add_subset (riscv_parse_subset_t *rps,
   int major_version = major;
   int minor_version = minor;
 
+  if (!rps->enable_experimental
+      && riscv_is_experimental_extension (subset))
+    {
+      rps->error_handler
+	(_("requires `-menable-experimental-extensions' for experimental "
+	   "ISA extension `%s'"), subset);
+      return;
+    }
+
   if ((major_version == RISCV_UNKNOWN_VERSION
        || minor_version == RISCV_UNKNOWN_VERSION)
       && rps->get_default_version != NULL)
diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
index 4e03ce1..1d98bf3 100644
--- a/bfd/elfxx-riscv.h
+++ b/bfd/elfxx-riscv.h
@@ -72,6 +72,7 @@ typedef struct
   void (*get_default_version) (const char *,
 			       int *,
 			       int *);
+  bfd_boolean enable_experimental;
 } riscv_parse_subset_t;
 
 extern bfd_boolean
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index d3cb941..f1f0581 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -186,16 +186,18 @@ struct riscv_set_options
   int relax; /* Emit relocs the linker is allowed to relax.  */
   int arch_attr; /* Emit arch attribute.  */
   int csr_check; /* Enable the CSR checking.  */
+  int enable_experimental; /* Enable experimental extensions.  */
 };
 
 static struct riscv_set_options riscv_opts =
 {
-  0,	/* pic */
-  0,	/* rvc */
-  0,	/* rve */
-  1,	/* relax */
-  DEFAULT_RISCV_ATTR, /* arch_attr */
-  0.	/* csr_check */
+  0,	/* pic  */
+  0,	/* rvc  */
+  0,	/* rve  */
+  1,	/* relax  */
+  DEFAULT_RISCV_ATTR,	/* arch_attr  */
+  0,	/* csr_check  */
+  0,	/* enable_experimental  */
 };
 
 static void
@@ -354,6 +356,7 @@ riscv_set_arch (const char *s)
   rps.error_handler = as_bad;
   rps.xlen = &xlen;
   rps.get_default_version = riscv_get_default_ext_version;
+  rps.enable_experimental = riscv_opts.enable_experimental;
 
   if (s == NULL)
     return;
@@ -2728,6 +2731,7 @@ enum options
   OPTION_NO_CSR_CHECK,
   OPTION_MISA_SPEC,
   OPTION_MPRIV_SPEC,
+  OPTION_ENABLE_EXPERIMENTAL,
   OPTION_END_OF_ENUM
 };
 
@@ -2746,6 +2750,7 @@ struct option md_longopts[] =
   {"mno-csr-check", no_argument, NULL, OPTION_NO_CSR_CHECK},
   {"misa-spec", required_argument, NULL, OPTION_MISA_SPEC},
   {"mpriv-spec", required_argument, NULL, OPTION_MPRIV_SPEC},
+  {"menable-experimental-extensions", no_argument, NULL, OPTION_ENABLE_EXPERIMENTAL},
 
   {NULL, no_argument, NULL, 0}
 };
@@ -2824,6 +2829,10 @@ md_parse_option (int c, const char *arg)
     case OPTION_MPRIV_SPEC:
       return riscv_set_default_priv_spec (arg);
 
+    case OPTION_ENABLE_EXPERIMENTAL:
+      riscv_opts.enable_experimental = TRUE;
+      break;
+
     default:
       return 0;
     }
diff --git a/gas/testsuite/gas/riscv/attribute-draft-b.d b/gas/testsuite/gas/riscv/attribute-draft-b.d
index 0af5b71..b1717d8 100644
--- a/gas/testsuite/gas/riscv/attribute-draft-b.d
+++ b/gas/testsuite/gas/riscv/attribute-draft-b.d
@@ -1,4 +1,4 @@
-#as: -march-attr -march=rv32ib_zba_zbb_zbc_zbe_zbf_zbm_zbp_zbr_zbs_zbt
+#as: -march-attr -march=rv32ib_zba_zbb_zbc_zbe_zbf_zbm_zbp_zbr_zbs_zbt -menable-experimental-extensions
 #readelf: -A
 #source: empty.s
 Attribute Section: riscv
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-32.d b/gas/testsuite/gas/riscv/bitmanip-insns-32.d
index ff1434c..bcf6b2c 100644
--- a/gas/testsuite/gas/riscv/bitmanip-insns-32.d
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-32.d
@@ -1,4 +1,4 @@
-#as: -march=rv32ib_zbr_zbt
+#as: -march=rv32ib_zbr_zbt -menable-experimental-extensions
 #source: bitmanip-insns.s
 #objdump: -dr -Mno-aliases
 
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-64.d b/gas/testsuite/gas/riscv/bitmanip-insns-64.d
index f097d87..51c8204 100644
--- a/gas/testsuite/gas/riscv/bitmanip-insns-64.d
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-64.d
@@ -1,4 +1,4 @@
-#as: -march=rv64ib_zbr_zbt -defsym __64_bit__=1
+#as: -march=rv64ib_zbr_zbt -defsym __64_bit__=1 -menable-experimental-extensions
 #source: bitmanip-insns.s
 #objdump: -dr -Mno-aliases
 
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d
index b0cdb16..0900c84 100644
--- a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-32.d
@@ -1,4 +1,4 @@
-#as: -march=rv32ib
+#as: -march=rv32ib -menable-experimental-extensions
 #source: bitmanip-insns-pseudo.s
 #objdump: -dr
 
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d
index 23b8b7b..01966bc 100644
--- a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-64.d
@@ -1,4 +1,4 @@
-#as: -march=rv64ib -defsym __64_bit__=1
+#as: -march=rv64ib -defsym __64_bit__=1 -menable-experimental-extensions
 #source: bitmanip-insns-pseudo.s
 #objdump: -dr
 
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-32.d b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-32.d
index 91190c8..2600efb 100644
--- a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-32.d
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-32.d
@@ -1,4 +1,4 @@
-#as: -march=rv32ib
+#as: -march=rv32ib -menable-experimental-extensions
 #source: bitmanip-insns-pseudo.s
 #objdump: -dr -Mno-aliases
 
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-64.d b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-64.d
index 187c487..5a095a3 100644
--- a/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-64.d
+++ b/gas/testsuite/gas/riscv/bitmanip-insns-pseudo-noalias-64.d
@@ -1,4 +1,4 @@
-#as: -march=rv64ib -defsym __64_bit__=1
+#as: -march=rv64ib -defsym __64_bit__=1 -menable-experimental-extensions
 #source: bitmanip-insns-pseudo.s
 #objdump: -dr -Mno-aliases
 
diff --git a/gas/testsuite/gas/riscv/march-fail-experimental.d b/gas/testsuite/gas/riscv/march-fail-experimental.d
new file mode 100644
index 0000000..0bf7e21
--- /dev/null
+++ b/gas/testsuite/gas/riscv/march-fail-experimental.d
@@ -0,0 +1,3 @@
+#as: -march=rv32ib_zba_zbb_zbc_zbe_zbf_zbm_zbp_zbr_zbs_zbt
+#source: empty.s
+#error_output: march-fail-experimental.l
diff --git a/gas/testsuite/gas/riscv/march-fail-experimental.l b/gas/testsuite/gas/riscv/march-fail-experimental.l
new file mode 100644
index 0000000..aaba4b4
--- /dev/null
+++ b/gas/testsuite/gas/riscv/march-fail-experimental.l
@@ -0,0 +1,12 @@
+.*Assembler messages:
+.*Error: requires `-menable-experimental-extensions' for experimental ISA extension `b'
+.*Error: requires `-menable-experimental-extensions' for experimental ISA extension `zba'
+.*Error: requires `-menable-experimental-extensions' for experimental ISA extension `zbb'
+.*Error: requires `-menable-experimental-extensions' for experimental ISA extension `zbc'
+.*Error: requires `-menable-experimental-extensions' for experimental ISA extension `zbe'
+.*Error: requires `-menable-experimental-extensions' for experimental ISA extension `zbf'
+.*Error: requires `-menable-experimental-extensions' for experimental ISA extension `zbm'
+.*Error: requires `-menable-experimental-extensions' for experimental ISA extension `zbp'
+.*Error: requires `-menable-experimental-extensions' for experimental ISA extension `zbr'
+.*Error: requires `-menable-experimental-extensions' for experimental ISA extension `zbs'
+.*Error: requires `-menable-experimental-extensions' for experimental ISA extension `zbt'
-- 
2.7.4


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

* Re: [PATCH 0/3] RISC-V: Add -menable-experimental-extensions and support bitmanip instructions
  2020-12-15 15:11 [PATCH 0/3] RISC-V: Add -menable-experimental-extensions and support bitmanip instructions Nelson Chu
                   ` (2 preceding siblings ...)
  2020-12-15 15:11 ` [PATCH 3/3] RISC-V: Add -menable-experimental-extensions option Nelson Chu
@ 2020-12-15 18:23 ` Palmer Dabbelt
  2020-12-16  2:05   ` Jim Wilson
  3 siblings, 1 reply; 8+ messages in thread
From: Palmer Dabbelt @ 2020-12-15 18:23 UTC (permalink / raw)
  To: nelson.chu
  Cc: binutils, claire, maxim.blinov, Jim Wilson, Andrew Waterman,
	kito.cheng, nelson.chu

On Tue, 15 Dec 2020 07:11:02 PST (-0800), nelson.chu@sifive.com wrote:
> Hi Guys,
>
> The -menable-experimental-extensions option was originally discussed
> in the following link,
> https://sourceware.org/pipermail/binutils/2020-December/114439.html

IIUC the plan is to start supporting draft extensions in binutils/GCC.  I don't
do a whole lot of binutils/GCC work any more so I'm not sure my opinion should
carry any weight, but I just wanted to point out that I think this is a bad
policy to adopt.  Specifically, I don't really care what the status of an
extension is at the RISC-V Foundation -- it's been made pretty clear over the
past year or two that even frozen extensions can change, so I don't really put
any weight behind them freezing an extension.  Hardware implementations of
draft extensions are being produced (just look at the various V implementations
being announced), which is essentially a necessity given the specification
development timeline.  There's nothing we can do about those issues over here,
they're really RISC-V Foundation problems.

The issue I have here is bringing code into binutils/GCC that we're intending
on quickly deprecating -- for example, it appears this one implements a
specification that hasn't even been versioned yet.  That is just not a way to
build out a useable ecosystem.  Imagine the spot we'll be in a year or two from
now trying to cobble together trees of the various systems projects that all
speak the same flavor of an extension (doubly so if we can't rely on version
numbers).

So I'm perfectly fine taking draft extensions (or vendor extensions), but only
if the plan is to support them for a reasonable time frame.  I'm not dead set
on what that timeline is and I don't know if binutils/GCC have standard
policies.  If there's something written down we should probably look into that,
but otherwise I'd aim for somewhere around three years as that seems to be
about the current delay between a draft specification being versioned and an
implementation being publicly available.

My personal bar for merging support for an extension would be the existence of
hardware that implements that extension.  That's kind of an arbitrary bar, but
it does at least mean that someone put enough thought into the extension that
it was deemed worth implementing.  Hardware can't disappear out from under us,
so it also means we'll at least be able to test the extensions over a
reasonable life cycle.  I'm not sure I'd even set the bar at "actual shipped
hardware on my desk", but something more along the lines of "a reputable
manufacturer has published a concrete timeline for availability of a dev board"
as that would let us get 0-day support for new hardware.  IMHO that's
essentially what the policy is for every other target, even if it might not be
explicitly written down as such.

That said, that's all my personal bar.  If you want to support draft extensions
earlier that's fine with me, it's your time and I'm fine with you spending it
however you want.  I just don't want those extensions disappearing out from
under me before we even know that they're going to remain unimplemented.  I
know it's more work to support multiple versions of extensions, but we're going
to have to do that at some point soon so we might as well just start taking
that seriously now.

> And we already have riscv bitmanip support in the riscv github,
> https://github.com/riscv/riscv-binutils-gdb/tree/riscv-binutils-2.35-rvb
>
> The bitmanip implementations are basically based on the 0.92 spec, but
> with the updates from tech-bitmanip mail list.  Eventually, these updates
> should be merged back to the spec, and we probably need a new 0.93 version
> or tag to make these changes stable.  However, the series of patches show
> how the -menable-experimental-extensions option works, and it is the same
> as what LLVM had done.  We are still the details of how this will work, so
> any suggestion and feedback is welcome.
>
> The tech-bitmanip mail list link,
> https://lists.riscv.org/g/tech-bitmanip/topic/summary_of_current_proposals/77924315?p=,,,20,0,0,0::recentpostdate%2Fsticky,,,20,2,0,77924315
>
> And here is the next steps of bitmanip ISA, which are arranged by Ken Dockser,
> https://docs.google.com/spreadsheets/d/1toaPZS7L3k__ApHa6QufF36ESNzG9-_NkxSvF4lKuwc/edit#gid=0
>
>
> BTW, the first patch is little bit difference compared to the
> riscv-binutils-2.35-rvb branch.  Here are the difference,
>
> * The spec said that (in Table 2.1) - B is all Zb* extensions except Zbr and
> Zbt.  Therefore, I change the INSN_CLASS_B_OR_ZBR/ZBT to INSN_CLASS_ZBR/ZBT.
>
> * I re-arranged the riscv-opcode table and collect ZB* together, to make the
> table cleaner.
>
> * rol[w] are ZBB in the tech-bitmanip, but they are ZBP in the 0.92 draft.
>
> * zext.w is addu.w in the tech-bitmanip, but it is packw before.
>
> However, we really need to update the bitmanip draft spec, according to the
> tech-bitmanip mails and the table arranged by Ken Dockser, and also get a
> new 0.93 version/tag to make the changes stable.
>
>
> Thanks
> Nelson
>
>
> Hi Claire and Maxim,
>
> I copy your commit name and mail from github, so if you prefer another ones,
> please feel free to let me know.  Thank you very much :)
>
> Nelson

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

* Re: [PATCH 0/3] RISC-V: Add -menable-experimental-extensions and support bitmanip instructions
  2020-12-15 18:23 ` [PATCH 0/3] RISC-V: Add -menable-experimental-extensions and support bitmanip instructions Palmer Dabbelt
@ 2020-12-16  2:05   ` Jim Wilson
  2020-12-18 20:21     ` Palmer Dabbelt
  0 siblings, 1 reply; 8+ messages in thread
From: Jim Wilson @ 2020-12-16  2:05 UTC (permalink / raw)
  To: Palmer Dabbelt
  Cc: Nelson Chu, Binutils, Clifford Wolf, Maxim Blinov,
	Andrew Waterman, Kito Cheng

On Tue, Dec 15, 2020 at 10:23 AM Palmer Dabbelt <palmer@dabbelt.com> wrote:

> IIUC the plan is to start supporting draft extensions in binutils/GCC.  I
> don't
> do a whole lot of binutils/GCC work any more so I'm not sure my opinion
> should
> carry any weight, but I just wanted to point out that I think this is a bad
> policy to adopt.
>

There are multiple practical problems here.

LLVM is already accepting draft extensions.  If we don't, then we risk
losing the user community.

There are development issues here.  We have at least 3 different git repos
where B extension work is happening.  It is a mess.  The only place where I
can get everyone to agree to do work is the FSF repo.  The FSF repo is also
the only place where everyone that should have write access does have write
access.

The github riscv repos are causing problems.  The longer we use them, the
more problems that they cause.  I need to deprecate them.  But I can't
deprecate them until I get everything upstream, and that includes the draft
extension work that we have been doing there.

>
> The issue I have here is bringing code into binutils/GCC that we're
> intending
> on quickly deprecating -- for example, it appears this one implements a
> specification that hasn't even been versioned yet.  That is just not a way
> to
> build out a useable ecosystem.  Imagine the spot we'll be in a year or two
> from
> now trying to cobble together trees of the various systems projects that
> all
> speak the same flavor of an extension (doubly so if we can't rely on
> version
> numbers).
>

The code we are adding is expected to be unchanged in the official version
of the zbb and zba extensions.  This is of course no guarantee, but we have
multiple parties that have agreed on this.  So this is not code that we are
expecting to deprecate.  The other ones are still in flux and may need to
be deprecated.  The only real problem is that the current updated draft
hasn't been given a version number yet.  I've asked for one to be assigned
to it so that the patches can use that version number.

My personal bar for merging support for an extension would be the existence
> of
> hardware that implements that extension.
>

RVI has already decided that there must be toolchain support before we can
have an official hardware extension.  If we can't have official toolchain
support until the hardware extension is official that we have a circular
dependency and are screwed.  Something needs to go first here, and it makes
sense that it is the toolchain support.  So we add toolchain support first
conditional on -menable-experimental-extensions, and then the hardware
extension becomes official, and then the toolchain support is no longer
conditional on -menable-experimental-extensions.

>
> That said, that's all my personal bar.  If you want to support draft
> extensions
> earlier that's fine with me, it's your time and I'm fine with you spending
> it
> however you want.  I just don't want those extensions disappearing out from
> under me before we even know that they're going to remain unimplemented.  I
> know it's more work to support multiple versions of extensions, but we're
> going
> to have to do that at some point soon so we might as well just start taking
> that seriously now.
>

The whole point of the -menable-experimental-extensions option is that the
support may change in an incompatible way tomorrow.  If you don't like
that, then don't use the option.

Yes, we need to support multiple versions of extensions, and we are adding
support for that, but this is impractical to do for draft extensions, as
they can change in difficult to support ways, including backward
compatibillity breaks.  Once an extension becomes official, then there
should be no backward incompatible changes, and it gets easier to support
multiple versions.

Jim

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

* Re: [PATCH 0/3] RISC-V: Add -menable-experimental-extensions and support bitmanip instructions
  2020-12-16  2:05   ` Jim Wilson
@ 2020-12-18 20:21     ` Palmer Dabbelt
  0 siblings, 0 replies; 8+ messages in thread
From: Palmer Dabbelt @ 2020-12-18 20:21 UTC (permalink / raw)
  To: Jim Wilson
  Cc: nelson.chu, binutils, claire, maxim.blinov, Andrew Waterman, kito.cheng

On Tue, 15 Dec 2020 18:05:16 PST (-0800), Jim Wilson wrote:
> On Tue, Dec 15, 2020 at 10:23 AM Palmer Dabbelt <palmer@dabbelt.com> wrote:
>
>> IIUC the plan is to start supporting draft extensions in binutils/GCC.  I
>> don't
>> do a whole lot of binutils/GCC work any more so I'm not sure my opinion
>> should
>> carry any weight, but I just wanted to point out that I think this is a bad
>> policy to adopt.
>>
>
> There are multiple practical problems here.
>
> LLVM is already accepting draft extensions.  If we don't, then we risk
> losing the user community.

I'm not sure I agree there.  A big part of the reason I'm arguing for keeping
the extensions on a branch is that I think users would be better served by the
branch.  Users (assuming we're talking distro toolchains here) are at least
months out of date WRT trunk, which means they're always going to have out of
date drafts and we're just going to tell them to go use trunk.  

> There are development issues here.  We have at least 3 different git repos
> where B extension work is happening.  It is a mess.  The only place where I
> can get everyone to agree to do work is the FSF repo.  The FSF repo is also
> the only place where everyone that should have write access does have write
> access.
>
> The github riscv repos are causing problems.  The longer we use them, the
> more problems that they cause.  I need to deprecate them.  But I can't
> deprecate them until I get everything upstream, and that includes the draft
> extension work that we have been doing there.

I agree.  I'm certainly not suggesting using those, FSF is the place to do it
(both for access reasons, and so we can deal with the copyright issues).  My
suggestion is simply an FSF branch (or FSF repo?  do we have multiple now that
we're on git?  I don't think it matters here).

>> The issue I have here is bringing code into binutils/GCC that we're
>> intending
>> on quickly deprecating -- for example, it appears this one implements a
>> specification that hasn't even been versioned yet.  That is just not a way
>> to
>> build out a useable ecosystem.  Imagine the spot we'll be in a year or two
>> from
>> now trying to cobble together trees of the various systems projects that
>> all
>> speak the same flavor of an extension (doubly so if we can't rely on
>> version
>> numbers).
>>
>
> The code we are adding is expected to be unchanged in the official version
> of the zbb and zba extensions.  This is of course no guarantee, but we have
> multiple parties that have agreed on this.  So this is not code that we are
> expecting to deprecate.  The other ones are still in flux and may need to
> be deprecated.  The only real problem is that the current updated draft
> hasn't been given a version number yet.  I've asked for one to be assigned
> to it so that the patches can use that version number.

If that's really the case then I don't see any reason to avoid putting those on
trunk.  I guess maybe I'd just a bit jaded here, but I feel like we get
promised that many things will get finished soon around every one of these
RISC-V conferences, only to have that swing the other way after a few weeks.
That kind of stuff is really why I'm inclined to just decouple ourselves
entirely from the foundation's processes and go the "support extant hardware"
route.

I would argue, though, that if we really do expect these to be unchanged in the
official version then why aren't we just supporting them in the same fashion we
support everything else?  Sure, if it turns out that things drift around a bit
or ratification fails we can deprecate it later (once we've convinved ourselves
nobody is implementing the old version), but that's a very different thing than
saying we're going to deprate stuff.  If people are starting to say they're
stable then people are going to start implementing them, so even if they do
change so we'll probably want to support these either way.

I definately agree we need a version number (and an actual stable one, not this
changing draft with a version stuff).

> My personal bar for merging support for an extension would be the existence
>> of
>> hardware that implements that extension.
>>
>
> RVI has already decided that there must be toolchain support before we can
> have an official hardware extension.  If we can't have official toolchain
> support until the hardware extension is official that we have a circular
> dependency and are screwed.  Something needs to go first here, and it makes
> sense that it is the toolchain support.  So we add toolchain support first
> conditional on -menable-experimental-extensions, and then the hardware
> extension becomes official, and then the toolchain support is no longer
> conditional on -menable-experimental-extensions.

Hasn't that always been the case?  We at least used to say people needed a
software stack before things were ratified, that's why things like the KVM port
showed up so early (the guys doing it though it would be important to have a
hypervisor extension ratified early on).  Most of that was pretty light-weight
on the toolchain side so I guess we just let it fly under the radar over here?
In practice all the software dependencies have shown up way before that
hardware implementation requirement, and my guess is that will remain the case.

IIUC "patches approved by the maintainers to be merged" has been sufficient to
freeze extensions for the ratification vote, at which point we can merge the
code.  That's generally been much faster than even getting the 45-day period
formally announced, much less the ratification vote.

The H extension and KVM port were this way last time I looked: the software was
done (or at least, targeted the draft that was supposed to be stable, things
drifted around abit) a year or two ago, we've just been waiting for the
hardware to show up so the extension can be properly frozen.  This is certainly
an example of the headaches involved in waiting for extensions to finish, but
also a good example of why we wait: the first time the KVM port was suggested
for merging was when we were in this "we're targeting this draft, with a few
spec differences, but that's going to be compatible with the final version"
stage.  It turns out we were a long way from a final spec, with at least one
more round of "it's actually done now" in the middle.

Maybe people are more likely to upgrade GCC versions these days than they were
before, as things don't break as much as they used to, but I'm still hesitant
to ask people to stick to the latest version.

>> That said, that's all my personal bar.  If you want to support draft
>> extensions
>> earlier that's fine with me, it's your time and I'm fine with you spending
>> it
>> however you want.  I just don't want those extensions disappearing out from
>> under me before we even know that they're going to remain unimplemented.  I
>> know it's more work to support multiple versions of extensions, but we're
>> going
>> to have to do that at some point soon so we might as well just start taking
>> that seriously now.
>>
>
> The whole point of the -menable-experimental-extensions option is that the
> support may change in an incompatible way tomorrow.  If you don't like
> that, then don't use the option.
>
> Yes, we need to support multiple versions of extensions, and we are adding
> support for that, but this is impractical to do for draft extensions, as
> they can change in difficult to support ways, including backward
> compatibillity breaks.  Once an extension becomes official, then there
> should be no backward incompatible changes, and it gets easier to support
> multiple versions.

I agree there should be no backwards-incompatible changes, but in practice
there are.  We've constructed a complicated rationale for the redefinition of
"I" not being a backwards-incompatible change (though TBH I don't really buy
it), but I really don't see an argument for the PMP thing: it is impossible to
build hardware that is compliant with both the pre-PMP spec and the post-PMP
spec (I guess that non-existent CSR clause could be used to justify the trap,
but I probably wouldn't buy that one either), and those differences broke the boot
on actual hardware.  That was obviously a mistake and we can produce software
that is compatible with both specifications so it's not that bad, but these
sorts of mistakes will continue to happen until we have users.

You guys do this way more than I do, so if you think this is the right way to
go then that's fine, let's do it.  I'm just not convinced.  I know
compatibility is more work, and I know I don't have a lot of ground to stand on
here when I'm throwing away an 8-month old QEMU, but I think this is going to
end up making more work for us in the long term than it saves in the short
term.  Happy to be wrong, though ;)

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

* Re: [PATCH 1/3] RISC-V: Support riscv bitmanip instructions.
  2020-12-15 15:11 ` [PATCH 1/3] RISC-V: Support riscv " Nelson Chu
@ 2021-01-04 23:48   ` Jim Wilson
  0 siblings, 0 replies; 8+ messages in thread
From: Jim Wilson @ 2021-01-04 23:48 UTC (permalink / raw)
  To: Nelson Chu
  Cc: Binutils, Clifford Wolf, Maxim Blinov, Andrew Waterman,
	Palmer Dabbelt, Kito Cheng

On Tue, Dec 15, 2020 at 7:11 AM Nelson Chu <nelson.chu@sifive.com> wrote:

> 2020-12-15  Claire Xenia Wolf  <claire@symbioticeda.com>
>             Jim Wilson  <jimw@sifive.com>
>             Maxim Blinov  <maxim.blinov@embecosm.com>
>             Kito Cheng  <kito.cheng@sifive.com>
>

I have one concern about this, which is that Claire's copyright assignment
was submitted before she changed her name.  I'm not sure of the legal
issues there.  I think one of us should ask the copyright clerk.  Worst
case we need a new copyright assignment.  Middle case we just use her
previous name in the ChangeLog entry.  Best case we can use her new name in
the changelog entry with an update to her copyright assignment records.
Though, oddly, checking for her assignment in the copyright.list file, I
can't find it now.  I am sure it was there before.  Maybe a mistake on the
FSF side?  Anyways, I sent email to the copyright clerk asking how to
handle this.

Jim

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

end of thread, other threads:[~2021-01-04 23:49 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-15 15:11 [PATCH 0/3] RISC-V: Add -menable-experimental-extensions and support bitmanip instructions Nelson Chu
2020-12-15 15:11 ` [PATCH 1/3] RISC-V: Support riscv " Nelson Chu
2021-01-04 23:48   ` Jim Wilson
2020-12-15 15:11 ` [PATCH 2/3] RISC-V: Define pseudo rev/orc/zip/unzip as alias instructions Nelson Chu
2020-12-15 15:11 ` [PATCH 3/3] RISC-V: Add -menable-experimental-extensions option Nelson Chu
2020-12-15 18:23 ` [PATCH 0/3] RISC-V: Add -menable-experimental-extensions and support bitmanip instructions Palmer Dabbelt
2020-12-16  2:05   ` Jim Wilson
2020-12-18 20:21     ` Palmer Dabbelt

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