[PATCH] RISC-V: Support riscv bitmanip frozen Zbs instructions (v0.94-draft)

Philipp Tomsich philipp.tomsich@vrull.eu
Sat Jan 9 15:54:10 GMT 2021


Add the frozen Zbs instructions (bset/bclr/binv/bext and their
immediate variants).

This patch is implemented according to the following link:
    https://github.com/riscv/riscv-bitmanip/pull/102

Functional validation has been performed with CF3, 500.perlbench_r,
502.gcc_r, and 548.exchange2_r.

For the SPEC2017 subset, the respective 'test' workloads were used.
Static insn counts from Zbs for the SPEC2017 subset (with LTO) were
observed as 4291 for 500.perlbench_r, 7247 for 502.gcc_r, and 15 for
exchange2_r.

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

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

 bfd/elfxx-riscv.c                           |  2 +-
 gas/config/tc-riscv.c                       |  2 ++
 gas/testsuite/gas/riscv/bitmanip-insns-32.d | 14 ++++++++++++-
 gas/testsuite/gas/riscv/bitmanip-insns-64.d | 18 +++++++++++++++-
 gas/testsuite/gas/riscv/bitmanip-insns.s    | 20 ++++++++++++++++++
 include/opcode/riscv-opc.h                  | 32 +++++++++++++++++++++++++++++
 include/opcode/riscv.h                      |  1 +
 opcodes/riscv-opc.c                         | 12 ++++++++++-
 8 files changed, 97 insertions(+), 4 deletions(-)

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 42aeed7..62d9f4f 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1597,7 +1597,7 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
 
 static const char * const riscv_std_z_ext_strtab[] =
 {
-  "zicsr", "zifencei", "zihintpause", "zba", "zbb", "zbc", NULL
+  "zicsr", "zifencei", "zihintpause", "zba", "zbb", "zbc", "zbs", 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 399283f..9384e0a 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -259,6 +259,8 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class)
       return riscv_subset_supports ("zbb");
     case INSN_CLASS_ZBC:
       return riscv_subset_supports ("zbc");
+    case INSN_CLASS_ZBS:
+      return riscv_subset_supports ("zbs");
     case INSN_CLASS_ZBA_OR_ZBB:
       return (riscv_subset_supports ("zba")
 	      || riscv_subset_supports ("zbb"));
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-32.d b/gas/testsuite/gas/riscv/bitmanip-insns-32.d
index b218f96..d9fd662 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=rv32i_zba_zbb_zbc
+#as: -march=rv32i_zba_zbb_zbc_zbs
 #source: bitmanip-insns.s
 #objdump: -dr -Mno-aliases
 
@@ -35,3 +35,15 @@ Disassembly of section .text:
 [ 	]+[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]+:[ 	]+48059513[ 	]+bclri[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f59513[ 	]+bclri[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+28059513[ 	]+bseti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f59513[ 	]+bseti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+68059513[ 	]+binvi[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f59513[ 	]+binvi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+4805d513[ 	]+bexti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f5d513[ 	]+bexti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+48c59533[ 	]+bclr[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+28c59533[ 	]+bset[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+68c59533[ 	]+binv[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5d533[ 	]+bext[ 	]+a0,a1,a2
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns-64.d b/gas/testsuite/gas/riscv/bitmanip-insns-64.d
index 9914f3e..758c47f 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=rv64i_zba_zbb_zbc -defsym __64_bit__=1
+#as: -march=rv64i_zba_zbb_zbc_zbs -defsym __64_bit__=1
 #source: bitmanip-insns.s
 #objdump: -dr -Mno-aliases
 
@@ -53,3 +53,19 @@ Disassembly of section .text:
 [ 	]+[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]+:[ 	]+48059513[ 	]+bclri[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f59513[ 	]+bclri[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+28059513[ 	]+bseti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+29f59513[ 	]+bseti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+68059513[ 	]+binvi[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+69f59513[ 	]+binvi[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+4805d513[ 	]+bexti[ 	]+a0,a1,0x0
+[ 	]+[0-9a-f]+:[ 	]+49f5d513[ 	]+bexti[ 	]+a0,a1,0x1f
+[ 	]+[0-9a-f]+:[ 	]+4bf59513[ 	]+bclri[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+2bf59513[ 	]+bseti[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+6bf59513[ 	]+binvi[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+4bf5d513[ 	]+bexti[ 	]+a0,a1,0x3f
+[ 	]+[0-9a-f]+:[ 	]+48c59533[ 	]+bclr[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+28c59533[ 	]+bset[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+68c59533[ 	]+binv[ 	]+a0,a1,a2
+[ 	]+[0-9a-f]+:[ 	]+48c5d533[ 	]+bext[ 	]+a0,a1,a2
diff --git a/gas/testsuite/gas/riscv/bitmanip-insns.s b/gas/testsuite/gas/riscv/bitmanip-insns.s
index b14e89c..caf8475 100644
--- a/gas/testsuite/gas/riscv/bitmanip-insns.s
+++ b/gas/testsuite/gas/riscv/bitmanip-insns.s
@@ -56,3 +56,23 @@
 	clmul	a0, a1, a2
 	clmulh	a0, a1, a2
 	clmulr	a0, a1, a2
+
+	#ZBS
+	bclri	a0, a1, 0
+	bclri	a0, a1, 31
+	bseti	a0, a1, 0
+	bseti	a0, a1, 31
+	binvi	a0, a1, 0
+	binvi	a0, a1, 31
+	bexti	a0, a1, 0
+	bexti	a0, a1, 31
+.ifdef __64_bit__
+	bclri	a0, a1, 63
+	bseti	a0, a1, 63
+	binvi	a0, a1, 63
+	bexti	a0, a1, 63
+.endif
+	bclr	a0, a1, a2
+	bset	a0, a1, a2
+	binv	a0, a1, a2
+	bext	a0, a1, a2
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 541a5a3..33f9ef4 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -263,6 +263,30 @@
 #define MASK_CLMULH  0xfe00707f
 #define MATCH_CLMULR 0xa002033
 #define MASK_CLMULR  0xfe00707f
+/* | 01001 | imm | rs1 | 001 | rd | 0010011 | BCLRI | */
+#define MATCH_BCLRI 0x48001013
+#define MASK_BCLRI  0xfc00707f
+/* | 00101 | imm | rs1 | 001 | rd | 0010011 | BSETI | */
+#define MATCH_BSETI 0x28001013
+#define MASK_BSETI  0xfc00707f
+/* | 01101 | imm | rs1 | 001 | rd | 0010011 | BINVI | */
+#define MATCH_BINVI 0x68001013
+#define MASK_BINVI  0xfc00707f
+/* | 01001 | imm | rs1 | 101 | rd | 0010011 | BEXTI | */
+#define MATCH_BEXTI 0x48005013
+#define MASK_BEXTI  0xfc00707f
+/* | 0100100 | rs2 | rs1 | 001 | rd | 0110011 | BCLR | */
+#define MATCH_BCLR  0x48001033
+#define MASK_BCLR   0xfe00707f
+/* | 0010100 | rs2 | rs1 | 001 | rd | 0110011 | BSET | */
+#define MATCH_BSET  0x28001033
+#define MASK_BSET   0xfe00707f
+/* | 0110100 | rs2 | rs1 | 001 | rd | 0110011 | BINV | */
+#define MATCH_BINV  0x68001033
+#define MASK_BINV   0xfe00707f
+/* | 0100100 | rs2 | rs1 | 101 | rd | 0110011 | BEXT | */
+#define MATCH_BEXT  0x48005033
+#define MASK_BEXT   0xfe00707f
 #define MATCH_AMOADD_W 0x202f
 #define MASK_AMOADD_W  0xf800707f
 #define MATCH_AMOXOR_W 0x2000202f
@@ -1082,6 +1106,14 @@ DECLARE_INSN(rolw, MATCH_ROLW, MASK_ROLW)
 DECLARE_INSN(clmul, MATCH_CLMUL, MASK_CLMUL)
 DECLARE_INSN(clmulr, MATCH_CLMULR, MASK_CLMULR)
 DECLARE_INSN(clmulh, MATCH_CLMULH, MASK_CLMULH)
+DECLARE_INSN(bclri, MATCH_BCLRI, MASK_BCLRI)
+DECLARE_INSN(bseti, MATCH_BSETI, MASK_BSETI)
+DECLARE_INSN(binvi, MATCH_BINVI, MASK_BINVI)
+DECLARE_INSN(bexti, MATCH_BEXTI, MASK_BEXTI)
+DECLARE_INSN(bclr, MATCH_BCLR, MASK_BCLR)
+DECLARE_INSN(bset, MATCH_BSET, MASK_BSET)
+DECLARE_INSN(binv, MATCH_BINV, MASK_BINV)
+DECLARE_INSN(bext, MATCH_BEXT, MASK_BEXT)
 DECLARE_INSN(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 02fb22f..8c328a0 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -315,6 +315,7 @@ enum riscv_insn_class
    INSN_CLASS_ZBA,
    INSN_CLASS_ZBB,
    INSN_CLASS_ZBC,
+   INSN_CLASS_ZBS,
    INSN_CLASS_ZBA_OR_ZBB,
   };
 
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 566b1f4..0d903dd 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -500,7 +500,7 @@ 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 - ZBA/ZBB/ZBC  */
+/* Bitmanip instruction subset - ZBA/ZBB/ZBC/ZBS  */
 {"sh1add",    0, INSN_CLASS_ZBA,   "d,s,t",  MATCH_SH1ADD, MASK_SH1ADD, match_opcode, 0 },
 {"sh2add",    0, INSN_CLASS_ZBA,   "d,s,t",  MATCH_SH2ADD, MASK_SH2ADD, match_opcode, 0 },
 {"sh3add",    0, INSN_CLASS_ZBA,   "d,s,t",  MATCH_SH3ADD, MASK_SH3ADD, match_opcode, 0 },
@@ -548,6 +548,15 @@ const struct riscv_opcode riscv_opcodes[] =
 {"clmulh",    0, INSN_CLASS_ZBC,   "d,s,t",  MATCH_CLMULH, MASK_CLMULH, match_opcode, 0 },
 {"clmulr",    0, INSN_CLASS_ZBC,   "d,s,t",  MATCH_CLMULR, MASK_CLMULR, match_opcode, 0 },
 
+{"bclri",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BCLRI, MASK_BCLRI, match_opcode, 0 },
+{"bseti",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BSETI, MASK_BSETI, match_opcode, 0 },
+{"binvi",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BINVI, MASK_BINVI, match_opcode, 0 },
+{"bexti",     0, INSN_CLASS_ZBS,   "d,s,>",  MATCH_BEXTI, MASK_BEXTI, match_opcode, 0 },
+{"bclr",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BCLR, MASK_BCLR, match_opcode, 0 },
+{"bset",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BSET, MASK_BSET, match_opcode, 0 },
+{"binv",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BINV, MASK_BINV, match_opcode, 0 },
+{"bext",      0, INSN_CLASS_ZBS,   "d,s,t",  MATCH_BEXT, MASK_BEXT, match_opcode, 0 },
+
 /* 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 },
@@ -1000,6 +1009,7 @@ const struct riscv_ext_version riscv_ext_version_table[] =
 {"zba", ISA_SPEC_CLASS_DRAFT, 0, 93},
 {"zbb", ISA_SPEC_CLASS_DRAFT, 0, 93},
 {"zbc", ISA_SPEC_CLASS_DRAFT, 0, 93},
+{"zbs", ISA_SPEC_CLASS_DRAFT, 0, 94},
 
 /* Terminate the list.  */
 {NULL, 0, 0, 0}
-- 
1.8.3.1



More information about the Binutils mailing list