public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/1] RISC-V: Add support for 'Zacas' atomic CAS
@ 2023-10-21  3:12 Tsukasa OI
  2023-10-21  3:12 ` [PATCH 1/1] " Tsukasa OI
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Tsukasa OI @ 2023-10-21  3:12 UTC (permalink / raw)
  To: Tsukasa OI, Palmer Dabbelt, Andrew Waterman, Jim Wilson,
	Nelson Chu, Kito Cheng
  Cc: binutils

Hi,

This patch adds support for now frozen (and being ratification) 'Zacas'
extension, containing atomic CAS instructions.

There are two patch sets by other people:

By Gianluca Guida (in 2023 May; RFC PATCH v2 at that time):
<https://sourceware.org/pipermail/binutils/2023-May/127700.html>
By Jiawei (in 2023 July; withdrawn):
<https://sourceware.org/pipermail/binutils/2023-July/128556.html>

... but independently developed.


Note that, this is one of the extensions that require the concept of
register pairs or register groups because it contains 2*XLEN-width
(double-word) CAS instructions.

We are better to reject invalid encodings considering the consensus after
the discussion of RISC-V GNU Toolchain meeting at 2022-10-06 (the feedback
of my proposal itself wasn't positive but we agreed that we are better to
detect invalid encodings as early as possible [I mean, in the assembler])
and the feedback to Gianluca's first RFC PATCH by Jan:
<https://sourceware.org/pipermail/binutils/2023-May/127407.html>


Differences to Gianluka's:
1.  Correct data size (INSN_DREF|INSN_*_BYTE) we are handling
2.  Make register pair matching function to be template
    to enable reusing this framework for upcoming P and existing Zdinx and
    V (many V cases are invalid only on certain runtime configuration and
    "always invalid" detectable cases are rare, but not zero).

Differences to Jiawei's:
1.  Correct support for register groups (fixed in Gianluka's RFC PATCH v2).


Thanks,
Tsukasa




Tsukasa OI (1):
  RISC-V: Add support for 'Zacas' atomic CAS

 bfd/elfxx-riscv.c                       |  6 +++++
 gas/testsuite/gas/riscv/zacas-32-fail.d |  2 ++
 gas/testsuite/gas/riscv/zacas-32-fail.l |  9 +++++++
 gas/testsuite/gas/riscv/zacas-32-fail.s | 10 +++++++
 gas/testsuite/gas/riscv/zacas-32.d      | 17 ++++++++++++
 gas/testsuite/gas/riscv/zacas-32.s      |  9 +++++++
 gas/testsuite/gas/riscv/zacas-64-fail.d |  2 ++
 gas/testsuite/gas/riscv/zacas-64-fail.l |  9 +++++++
 gas/testsuite/gas/riscv/zacas-64-fail.s | 10 +++++++
 gas/testsuite/gas/riscv/zacas-64.d      | 17 ++++++++++++
 gas/testsuite/gas/riscv/zacas-64.s      |  9 +++++++
 include/opcode/riscv-opc.h              | 11 ++++++++
 include/opcode/riscv.h                  |  1 +
 opcodes/riscv-opc.c                     | 36 +++++++++++++++++++++++++
 14 files changed, 148 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.d
 create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.l
 create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.s
 create mode 100644 gas/testsuite/gas/riscv/zacas-32.d
 create mode 100644 gas/testsuite/gas/riscv/zacas-32.s
 create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.d
 create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.l
 create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.s
 create mode 100644 gas/testsuite/gas/riscv/zacas-64.d
 create mode 100644 gas/testsuite/gas/riscv/zacas-64.s


base-commit: 0e17d3fc080f543d81e6c2520ba0bd8046ea3a95
-- 
2.42.0


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

* [PATCH 1/1] RISC-V: Add support for 'Zacas' atomic CAS
  2023-10-21  3:12 [PATCH 0/1] RISC-V: Add support for 'Zacas' atomic CAS Tsukasa OI
@ 2023-10-21  3:12 ` Tsukasa OI
  2023-10-22  3:54 ` [PATCH v2] " Tsukasa OI
  2023-12-06 18:39 ` [PATCH 0/1] " Gianluca Guida
  2 siblings, 0 replies; 11+ messages in thread
From: Tsukasa OI @ 2023-10-21  3:12 UTC (permalink / raw)
  To: Tsukasa OI, Palmer Dabbelt, Andrew Waterman, Jim Wilson,
	Nelson Chu, Kito Cheng
  Cc: binutils

From: Tsukasa OI <research_trasio@irq.a4lg.com>

This commit adds support for the 'Zacas' extension, adding atomic CAS
instructions.  Beware that this extension also introduces the concept of
register pairs and it checks the validity of rs1 and rs2 if applicable.

This is based on the latest (frozen) draft:
<https://github.com/riscv/riscv-zacas/releases/tag/v1.0-rc5>

bfd/ChangeLog:

	* elfxx-riscv.c
	(riscv_implicit_subsets): Make 'Zacas' to imply 'A' extension.
	(riscv_supported_std_z_ext): Add 'Zacas' to the supported list.
	(riscv_multi_subset_supports, riscv_multi_subset_supports_ext):
	Add handling for new instruction class.

gas/ChangeLog:

	* testsuite/gas/riscv/zacas-32.s: New test.
	* testsuite/gas/riscv/zacas-32.d: Likewise.
	* testsuite/gas/riscv/zacas-64.s: Likewise.
	* testsuite/gas/riscv/zacas-64.d: Likewise.
	* testsuite/gas/riscv/zacas-32-fail.s: New failure test.
	* testsuite/gas/riscv/zacas-32-fail.d: Likewise.
	* testsuite/gas/riscv/zacas-32-fail.l: Likewise.
	* testsuite/gas/riscv/zacas-64-fail.s: New failure test.
	* testsuite/gas/riscv/zacas-64-fail.d: Likewise.
	* testsuite/gas/riscv/zacas-64-fail.l: Likewise.

include/ChangeLog:

	* opcode/riscv-opc.h (MATCH_AMOCAS_D, MASK_AMOCAS_D,
	MATCH_AMOCAS_Q, MASK_AMOCAS_Q, MATCH_AMOCAS_W,
	MASK_AMOCAS_W): New.
	* opcode/riscv.h (enum riscv_insn_class): Add new instruction
	class INSN_CLASS_ZACAS.

opcodes/ChangeLog:

	* riscv-opc.c (REGGROUP_REGS_x, REGGROUP_REGS_1, REGGROUP_REGS_2,
	DEFINE_MATCH_FUNC_R): New match function template with register
	groups.
	(match_reggroup_r_1_1_1, match_reggroup_r_1_2_2): New.
	(riscv_opcodes): Add atomic CAS instructions.
---
 bfd/elfxx-riscv.c                       |  6 +++++
 gas/testsuite/gas/riscv/zacas-32-fail.d |  2 ++
 gas/testsuite/gas/riscv/zacas-32-fail.l |  9 +++++++
 gas/testsuite/gas/riscv/zacas-32-fail.s | 10 +++++++
 gas/testsuite/gas/riscv/zacas-32.d      | 17 ++++++++++++
 gas/testsuite/gas/riscv/zacas-32.s      |  9 +++++++
 gas/testsuite/gas/riscv/zacas-64-fail.d |  2 ++
 gas/testsuite/gas/riscv/zacas-64-fail.l |  9 +++++++
 gas/testsuite/gas/riscv/zacas-64-fail.s | 10 +++++++
 gas/testsuite/gas/riscv/zacas-64.d      | 17 ++++++++++++
 gas/testsuite/gas/riscv/zacas-64.s      |  9 +++++++
 include/opcode/riscv-opc.h              | 11 ++++++++
 include/opcode/riscv.h                  |  1 +
 opcodes/riscv-opc.c                     | 36 +++++++++++++++++++++++++
 14 files changed, 148 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.d
 create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.l
 create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.s
 create mode 100644 gas/testsuite/gas/riscv/zacas-32.d
 create mode 100644 gas/testsuite/gas/riscv/zacas-32.s
 create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.d
 create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.l
 create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.s
 create mode 100644 gas/testsuite/gas/riscv/zacas-64.d
 create mode 100644 gas/testsuite/gas/riscv/zacas-64.s

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index c070394a3667..b7e067794ba8 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1148,6 +1148,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"zhinx", "zhinxmin",	check_implicit_always},
   {"zhinxmin", "zfinx",	check_implicit_always},
   {"zfinx", "zicsr",	check_implicit_always},
+  {"zacas", "a",	check_implicit_always},
   {"zk", "zkn",		check_implicit_always},
   {"zk", "zkr",		check_implicit_always},
   {"zk", "zkt",		check_implicit_always},
@@ -1259,6 +1260,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
   {"zihintntl",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zihintpause",	ISA_SPEC_CLASS_DRAFT,		2, 0,  0 },
   {"zmmul",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
+  {"zacas",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zawrs",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zfa",		ISA_SPEC_CLASS_DRAFT,		0, 1,  0 },
   {"zfh",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
@@ -2409,6 +2411,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return riscv_subset_supports (rps, "zmmul");
     case INSN_CLASS_A:
       return riscv_subset_supports (rps, "a");
+    case INSN_CLASS_ZACAS:
+      return riscv_subset_supports (rps, "zacas");
     case INSN_CLASS_ZAWRS:
       return riscv_subset_supports (rps, "zawrs");
     case INSN_CLASS_F:
@@ -2619,6 +2623,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return _ ("m' or `zmmul");
     case INSN_CLASS_A:
       return "a";
+    case INSN_CLASS_ZACAS:
+      return "zacas";
     case INSN_CLASS_ZAWRS:
       return "zawrs";
     case INSN_CLASS_F:
diff --git a/gas/testsuite/gas/riscv/zacas-32-fail.d b/gas/testsuite/gas/riscv/zacas-32-fail.d
new file mode 100644
index 000000000000..12c1bd90ac86
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-32-fail.d
@@ -0,0 +1,2 @@
+#as: -march=rv32i_zacas
+#error_output: zacas-32-fail.l
diff --git a/gas/testsuite/gas/riscv/zacas-32-fail.l b/gas/testsuite/gas/riscv/zacas-32-fail.l
new file mode 100644
index 000000000000..944a66ba7806
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-32-fail.l
@@ -0,0 +1,9 @@
+.*: Assembler messages:
+.*: Error: illegal operands `amocas\.d a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.d a0,a5,\(a3\)'
+.*: Error: illegal operands `amocas\.d\.aq a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.d\.aq a0,a5,\(a3\)'
+.*: Error: illegal operands `amocas\.d\.rl a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.d\.rl a0,a5,\(a3\)'
+.*: Error: illegal operands `amocas\.d\.aqrl a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.d\.aqrl a0,a5,\(a3\)'
diff --git a/gas/testsuite/gas/riscv/zacas-32-fail.s b/gas/testsuite/gas/riscv/zacas-32-fail.s
new file mode 100644
index 000000000000..650ea1d8b6f2
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-32-fail.s
@@ -0,0 +1,10 @@
+target:
+	# amocas.d (RV32): rd (operand 1) and rs2 (operand 2) must be even.
+	amocas.d	a1, a4, (a3)
+	amocas.d	a0, a5, (a3)
+	amocas.d.aq	a1, a4, (a3)
+	amocas.d.aq	a0, a5, (a3)
+	amocas.d.rl	a1, a4, (a3)
+	amocas.d.rl	a0, a5, (a3)
+	amocas.d.aqrl	a1, a4, (a3)
+	amocas.d.aqrl	a0, a5, (a3)
diff --git a/gas/testsuite/gas/riscv/zacas-32.d b/gas/testsuite/gas/riscv/zacas-32.d
new file mode 100644
index 000000000000..60f4fe09f866
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-32.d
@@ -0,0 +1,17 @@
+#as: -march=rv32i_zacas
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+28f6a5af[ 	]+amocas\.w[ 		]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2cf6a5af[ 	]+amocas\.w\.aq[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2af6a5af[ 	]+amocas\.w\.rl[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ef6a5af[ 	]+amocas\.w\.aqrl[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+28e6b52f[ 	]+amocas\.d[ 		]+a0,a4,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ce6b52f[ 	]+amocas\.d\.aq[ 	]+a0,a4,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ae6b52f[ 	]+amocas\.d\.rl[ 	]+a0,a4,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ee6b52f[ 	]+amocas\.d\.aqrl[ 	]+a0,a4,\(a3\)
diff --git a/gas/testsuite/gas/riscv/zacas-32.s b/gas/testsuite/gas/riscv/zacas-32.s
new file mode 100644
index 000000000000..c12c0e42f338
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-32.s
@@ -0,0 +1,9 @@
+target:
+	amocas.w	a1, a5, (a3)
+	amocas.w.aq	a1, a5, (a3)
+	amocas.w.rl	a1, a5, (a3)
+	amocas.w.aqrl	a1, a5, (a3)
+	amocas.d	a0, a4, (a3)
+	amocas.d.aq	a0, a4, (a3)
+	amocas.d.rl	a0, a4, (a3)
+	amocas.d.aqrl	a0, a4, (a3)
diff --git a/gas/testsuite/gas/riscv/zacas-64-fail.d b/gas/testsuite/gas/riscv/zacas-64-fail.d
new file mode 100644
index 000000000000..e1910d81f9e2
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-64-fail.d
@@ -0,0 +1,2 @@
+#as: -march=rv64i_zacas
+#error_output: zacas-64-fail.l
diff --git a/gas/testsuite/gas/riscv/zacas-64-fail.l b/gas/testsuite/gas/riscv/zacas-64-fail.l
new file mode 100644
index 000000000000..74495401e153
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-64-fail.l
@@ -0,0 +1,9 @@
+.*: Assembler messages:
+.*: Error: illegal operands `amocas\.q a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.q a0,a5,\(a3\)'
+.*: Error: illegal operands `amocas\.q\.aq a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.q\.aq a0,a5,\(a3\)'
+.*: Error: illegal operands `amocas\.q\.rl a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.q\.rl a0,a5,\(a3\)'
+.*: Error: illegal operands `amocas\.q\.aqrl a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.q\.aqrl a0,a5,\(a3\)'
diff --git a/gas/testsuite/gas/riscv/zacas-64-fail.s b/gas/testsuite/gas/riscv/zacas-64-fail.s
new file mode 100644
index 000000000000..96ee4a378bf5
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-64-fail.s
@@ -0,0 +1,10 @@
+target:
+	# amocas.q (RV64): rd (operand 1) and rs2 (operand 2) must be even.
+	amocas.q	a1, a4, (a3)
+	amocas.q	a0, a5, (a3)
+	amocas.q.aq	a1, a4, (a3)
+	amocas.q.aq	a0, a5, (a3)
+	amocas.q.rl	a1, a4, (a3)
+	amocas.q.rl	a0, a5, (a3)
+	amocas.q.aqrl	a1, a4, (a3)
+	amocas.q.aqrl	a0, a5, (a3)
diff --git a/gas/testsuite/gas/riscv/zacas-64.d b/gas/testsuite/gas/riscv/zacas-64.d
new file mode 100644
index 000000000000..99fdfdb7db3f
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-64.d
@@ -0,0 +1,17 @@
+#as: -march=rv64i_zacas
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+28f6b5af[ 	]+amocas\.d[ 		]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2cf6b5af[ 	]+amocas\.d\.aq[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2af6b5af[ 	]+amocas\.d\.rl[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ef6b5af[ 	]+amocas\.d\.aqrl[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+28e6c52f[ 	]+amocas\.q[ 		]+a0,a4,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ce6c52f[ 	]+amocas\.q\.aq[ 	]+a0,a4,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ae6c52f[ 	]+amocas\.q\.rl[ 	]+a0,a4,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ee6c52f[ 	]+amocas\.q\.aqrl[ 	]+a0,a4,\(a3\)
diff --git a/gas/testsuite/gas/riscv/zacas-64.s b/gas/testsuite/gas/riscv/zacas-64.s
new file mode 100644
index 000000000000..d5b6603f6141
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-64.s
@@ -0,0 +1,9 @@
+target:
+	amocas.d	a1, a5, (a3)
+	amocas.d.aq	a1, a5, (a3)
+	amocas.d.rl	a1, a5, (a3)
+	amocas.d.aqrl	a1, a5, (a3)
+	amocas.q	a0, a4, (a3)
+	amocas.q.aq	a0, a4, (a3)
+	amocas.q.rl	a0, a4, (a3)
+	amocas.q.aqrl	a0, a4, (a3)
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 375483500e2a..8fb59e3db93e 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -2315,6 +2315,13 @@
 #define MASK_C_NTL_S1 0xffff
 #define MATCH_C_NTL_ALL 0x9016
 #define MASK_C_NTL_ALL 0xffff
+/* Zacas instructions.  */
+#define MATCH_AMOCAS_D 0x2800302f
+#define MASK_AMOCAS_D 0xf800707f
+#define MATCH_AMOCAS_Q 0x2800402f
+#define MASK_AMOCAS_Q 0xf800707f
+#define MATCH_AMOCAS_W 0x2800202f
+#define MASK_AMOCAS_W 0xf800707f
 /* Zawrs instructions.  */
 #define MATCH_WRS_NTO 0x00d00073
 #define MASK_WRS_NTO 0xffffffff
@@ -3370,6 +3377,10 @@ DECLARE_INSN(c_ntl_p1, MATCH_C_NTL_P1, MASK_C_NTL_P1)
 DECLARE_INSN(c_ntl_pall, MATCH_C_NTL_PALL, MASK_C_NTL_PALL)
 DECLARE_INSN(c_ntl_s1, MATCH_C_NTL_S1, MASK_C_NTL_S1)
 DECLARE_INSN(c_ntl_all, MATCH_C_NTL_ALL, MASK_C_NTL_ALL)
+/* Zacas instructions.  */
+DECLARE_INSN(amocas_d, MATCH_AMOCAS_D, MASK_AMOCAS_D)
+DECLARE_INSN(amocas_q, MATCH_AMOCAS_Q, MASK_AMOCAS_Q)
+DECLARE_INSN(amocas_w, MATCH_AMOCAS_W, MASK_AMOCAS_W)
 /* Zawrs instructions.  */
 DECLARE_INSN(wrs_nto, MATCH_WRS_NTO, MASK_WRS_NTO)
 DECLARE_INSN(wrs_sto, MATCH_WRS_STO, MASK_WRS_STO)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 93dd5169ebce..aefbfc7db81e 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -396,6 +396,7 @@ enum riscv_insn_class
   INSN_CLASS_ZIHINTNTL_AND_C,
   INSN_CLASS_ZIHINTPAUSE,
   INSN_CLASS_ZMMUL,
+  INSN_CLASS_ZACAS,
   INSN_CLASS_ZAWRS,
   INSN_CLASS_F_INX,
   INSN_CLASS_D_INX,
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 8e0ae85eb064..58087ca19cac 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -290,6 +290,24 @@ match_vd_eq_vs1_eq_vs2 (const struct riscv_opcode *op,
   return match_opcode (op, insn) && vd == vs1 && vs1 == vs2;
 }
 
+/* Instructions with register groups.  */
+
+#define DEFINE_MATCH_FUNC_R(G_RD,G_RS1,G_RS2) \
+  static int \
+  match_reggroup_r_##G_RD##_##G_RS1##_##G_RS2 (const struct riscv_opcode *op, \
+					       insn_t insn) \
+  { \
+    int rd = (insn & MASK_RD) >> OP_SH_RD; \
+    int rs1 = (insn & MASK_RS1) >> OP_SH_RS1; \
+    int rs2 = (insn & MASK_RS2) >> OP_SH_RS2; \
+    return match_opcode (op, insn) \
+	   && (rd % G_RD == 0) \
+	   && (rs1 % G_RS1 == 0) \
+	   && (rs2 % G_RS2 == 0); \
+  }
+DEFINE_MATCH_FUNC_R(1, 1, 1)
+DEFINE_MATCH_FUNC_R(2, 1, 2)
+
 static int
 match_th_load_inc(const struct riscv_opcode *op,
 		  insn_t insn)
@@ -982,6 +1000,24 @@ const struct riscv_opcode riscv_opcodes[] =
 {"czero.eqz",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_EQZ, MASK_CZERO_EQZ, match_opcode, 0 },
 {"czero.nez",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_NEZ, MASK_CZERO_NEZ, match_opcode, 0 },
 
+/* Zacas instructions.  */
+{"amocas.w",       0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"amocas.w.aq",    0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W|MASK_AQ, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"amocas.w.rl",    0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W|MASK_RL, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"amocas.w.aqrl",  0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W|MASK_AQRL, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"amocas.d",      32, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_8_BYTE },
+{"amocas.d",      64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_1_1_1, INSN_DREF|INSN_8_BYTE },
+{"amocas.d.aq",   32, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_AQ, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_8_BYTE },
+{"amocas.d.aq",   64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_AQ, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_1_1_1, INSN_DREF|INSN_8_BYTE },
+{"amocas.d.rl",   32, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_RL, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_8_BYTE },
+{"amocas.d.rl",   64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_RL, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_1_1_1, INSN_DREF|INSN_8_BYTE },
+{"amocas.d.aqrl", 32, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_AQRL, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_8_BYTE },
+{"amocas.d.aqrl", 64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_AQRL, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_1_1_1, INSN_DREF|INSN_8_BYTE },
+{"amocas.q",      64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_Q, MASK_AMOCAS_Q|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_16_BYTE },
+{"amocas.q.aq",   64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_Q|MASK_AQ, MASK_AMOCAS_Q|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_16_BYTE },
+{"amocas.q.rl",   64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_Q|MASK_RL, MASK_AMOCAS_Q|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_16_BYTE },
+{"amocas.q.aqrl", 64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_Q|MASK_AQRL, MASK_AMOCAS_Q|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_16_BYTE },
+
 /* Zawrs instructions.  */
 {"wrs.nto",    0, INSN_CLASS_ZAWRS, "", MATCH_WRS_NTO, MASK_WRS_NTO, match_opcode, 0 },
 {"wrs.sto",    0, INSN_CLASS_ZAWRS, "", MATCH_WRS_STO, MASK_WRS_STO, match_opcode, 0 },
-- 
2.42.0


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

* [PATCH v2] RISC-V: Add support for 'Zacas' atomic CAS
  2023-10-21  3:12 [PATCH 0/1] RISC-V: Add support for 'Zacas' atomic CAS Tsukasa OI
  2023-10-21  3:12 ` [PATCH 1/1] " Tsukasa OI
@ 2023-10-22  3:54 ` Tsukasa OI
  2023-10-22  3:57   ` [REVIEW ONLY] UNRATIFIED RISC-V: Add support for 'Zabha' subword AMO extension Tsukasa OI
                     ` (2 more replies)
  2023-12-06 18:39 ` [PATCH 0/1] " Gianluca Guida
  2 siblings, 3 replies; 11+ messages in thread
From: Tsukasa OI @ 2023-10-22  3:54 UTC (permalink / raw)
  To: Tsukasa OI, Palmer Dabbelt, Andrew Waterman, Jim Wilson,
	Nelson Chu, Kito Cheng
  Cc: binutils

From: Tsukasa OI <research_trasio@irq.a4lg.com>

This commit adds support for the 'Zacas' extension, adding atomic CAS
instructions.  Beware that this extension also introduces the concept of
register pairs and it checks the validity of rs1 and rs2 if applicable.

This is based on the latest (frozen) draft:
<https://github.com/riscv/riscv-zacas/releases/tag/v1.0-rc5>

bfd/ChangeLog:

	* elfxx-riscv.c
	(riscv_implicit_subsets): Make 'Zacas' to imply 'A' extension.
	(riscv_supported_std_z_ext): Add 'Zacas' to the supported list.
	(riscv_multi_subset_supports, riscv_multi_subset_supports_ext):
	Add handling for new instruction class.

gas/ChangeLog:

	* testsuite/gas/riscv/zacas-32.s: New test.
	* testsuite/gas/riscv/zacas-32.d: Likewise.
	* testsuite/gas/riscv/zacas-64.s: Likewise.
	* testsuite/gas/riscv/zacas-64.d: Likewise.
	* testsuite/gas/riscv/zacas-32-fail.s: New failure test.
	* testsuite/gas/riscv/zacas-32-fail.d: Likewise.
	* testsuite/gas/riscv/zacas-32-fail.l: Likewise.
	* testsuite/gas/riscv/zacas-64-fail.s: New failure test.
	* testsuite/gas/riscv/zacas-64-fail.d: Likewise.
	* testsuite/gas/riscv/zacas-64-fail.l: Likewise.

include/ChangeLog:

	* opcode/riscv-opc.h (MATCH_AMOCAS_D, MASK_AMOCAS_D,
	MATCH_AMOCAS_Q, MASK_AMOCAS_Q, MATCH_AMOCAS_W,
	MASK_AMOCAS_W): New.
	* opcode/riscv.h (enum riscv_insn_class): Add new instruction
	class INSN_CLASS_ZACAS.

opcodes/ChangeLog:

	* riscv-opc.c (REGGROUP_REGS_x, REGGROUP_REGS_1, REGGROUP_REGS_2,
	DEFINE_MATCH_FUNC_R): New match function template with register
	groups.
	(match_reggroup_r_1_1_1, match_reggroup_r_1_2_2): New.
	(riscv_opcodes): Add atomic CAS instructions.
---
 bfd/elfxx-riscv.c                       |  6 +++++
 gas/testsuite/gas/riscv/zacas-32-fail.d |  2 ++
 gas/testsuite/gas/riscv/zacas-32-fail.l |  9 +++++++
 gas/testsuite/gas/riscv/zacas-32-fail.s | 10 +++++++
 gas/testsuite/gas/riscv/zacas-32.d      | 17 ++++++++++++
 gas/testsuite/gas/riscv/zacas-32.s      |  9 +++++++
 gas/testsuite/gas/riscv/zacas-64-fail.d |  2 ++
 gas/testsuite/gas/riscv/zacas-64-fail.l |  9 +++++++
 gas/testsuite/gas/riscv/zacas-64-fail.s | 10 +++++++
 gas/testsuite/gas/riscv/zacas-64.d      | 21 +++++++++++++++
 gas/testsuite/gas/riscv/zacas-64.s      | 13 +++++++++
 include/opcode/riscv-opc.h              | 11 ++++++++
 include/opcode/riscv.h                  |  1 +
 opcodes/riscv-opc.c                     | 36 +++++++++++++++++++++++++
 14 files changed, 156 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.d
 create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.l
 create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.s
 create mode 100644 gas/testsuite/gas/riscv/zacas-32.d
 create mode 100644 gas/testsuite/gas/riscv/zacas-32.s
 create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.d
 create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.l
 create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.s
 create mode 100644 gas/testsuite/gas/riscv/zacas-64.d
 create mode 100644 gas/testsuite/gas/riscv/zacas-64.s

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index c070394a3667..b7e067794ba8 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1148,6 +1148,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"zhinx", "zhinxmin",	check_implicit_always},
   {"zhinxmin", "zfinx",	check_implicit_always},
   {"zfinx", "zicsr",	check_implicit_always},
+  {"zacas", "a",	check_implicit_always},
   {"zk", "zkn",		check_implicit_always},
   {"zk", "zkr",		check_implicit_always},
   {"zk", "zkt",		check_implicit_always},
@@ -1259,6 +1260,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
   {"zihintntl",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zihintpause",	ISA_SPEC_CLASS_DRAFT,		2, 0,  0 },
   {"zmmul",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
+  {"zacas",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zawrs",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zfa",		ISA_SPEC_CLASS_DRAFT,		0, 1,  0 },
   {"zfh",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
@@ -2409,6 +2411,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return riscv_subset_supports (rps, "zmmul");
     case INSN_CLASS_A:
       return riscv_subset_supports (rps, "a");
+    case INSN_CLASS_ZACAS:
+      return riscv_subset_supports (rps, "zacas");
     case INSN_CLASS_ZAWRS:
       return riscv_subset_supports (rps, "zawrs");
     case INSN_CLASS_F:
@@ -2619,6 +2623,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return _ ("m' or `zmmul");
     case INSN_CLASS_A:
       return "a";
+    case INSN_CLASS_ZACAS:
+      return "zacas";
     case INSN_CLASS_ZAWRS:
       return "zawrs";
     case INSN_CLASS_F:
diff --git a/gas/testsuite/gas/riscv/zacas-32-fail.d b/gas/testsuite/gas/riscv/zacas-32-fail.d
new file mode 100644
index 000000000000..12c1bd90ac86
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-32-fail.d
@@ -0,0 +1,2 @@
+#as: -march=rv32i_zacas
+#error_output: zacas-32-fail.l
diff --git a/gas/testsuite/gas/riscv/zacas-32-fail.l b/gas/testsuite/gas/riscv/zacas-32-fail.l
new file mode 100644
index 000000000000..944a66ba7806
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-32-fail.l
@@ -0,0 +1,9 @@
+.*: Assembler messages:
+.*: Error: illegal operands `amocas\.d a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.d a0,a5,\(a3\)'
+.*: Error: illegal operands `amocas\.d\.aq a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.d\.aq a0,a5,\(a3\)'
+.*: Error: illegal operands `amocas\.d\.rl a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.d\.rl a0,a5,\(a3\)'
+.*: Error: illegal operands `amocas\.d\.aqrl a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.d\.aqrl a0,a5,\(a3\)'
diff --git a/gas/testsuite/gas/riscv/zacas-32-fail.s b/gas/testsuite/gas/riscv/zacas-32-fail.s
new file mode 100644
index 000000000000..650ea1d8b6f2
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-32-fail.s
@@ -0,0 +1,10 @@
+target:
+	# amocas.d (RV32): rd (operand 1) and rs2 (operand 2) must be even.
+	amocas.d	a1, a4, (a3)
+	amocas.d	a0, a5, (a3)
+	amocas.d.aq	a1, a4, (a3)
+	amocas.d.aq	a0, a5, (a3)
+	amocas.d.rl	a1, a4, (a3)
+	amocas.d.rl	a0, a5, (a3)
+	amocas.d.aqrl	a1, a4, (a3)
+	amocas.d.aqrl	a0, a5, (a3)
diff --git a/gas/testsuite/gas/riscv/zacas-32.d b/gas/testsuite/gas/riscv/zacas-32.d
new file mode 100644
index 000000000000..60f4fe09f866
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-32.d
@@ -0,0 +1,17 @@
+#as: -march=rv32i_zacas
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+28f6a5af[ 	]+amocas\.w[ 		]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2cf6a5af[ 	]+amocas\.w\.aq[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2af6a5af[ 	]+amocas\.w\.rl[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ef6a5af[ 	]+amocas\.w\.aqrl[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+28e6b52f[ 	]+amocas\.d[ 		]+a0,a4,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ce6b52f[ 	]+amocas\.d\.aq[ 	]+a0,a4,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ae6b52f[ 	]+amocas\.d\.rl[ 	]+a0,a4,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ee6b52f[ 	]+amocas\.d\.aqrl[ 	]+a0,a4,\(a3\)
diff --git a/gas/testsuite/gas/riscv/zacas-32.s b/gas/testsuite/gas/riscv/zacas-32.s
new file mode 100644
index 000000000000..c12c0e42f338
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-32.s
@@ -0,0 +1,9 @@
+target:
+	amocas.w	a1, a5, (a3)
+	amocas.w.aq	a1, a5, (a3)
+	amocas.w.rl	a1, a5, (a3)
+	amocas.w.aqrl	a1, a5, (a3)
+	amocas.d	a0, a4, (a3)
+	amocas.d.aq	a0, a4, (a3)
+	amocas.d.rl	a0, a4, (a3)
+	amocas.d.aqrl	a0, a4, (a3)
diff --git a/gas/testsuite/gas/riscv/zacas-64-fail.d b/gas/testsuite/gas/riscv/zacas-64-fail.d
new file mode 100644
index 000000000000..e1910d81f9e2
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-64-fail.d
@@ -0,0 +1,2 @@
+#as: -march=rv64i_zacas
+#error_output: zacas-64-fail.l
diff --git a/gas/testsuite/gas/riscv/zacas-64-fail.l b/gas/testsuite/gas/riscv/zacas-64-fail.l
new file mode 100644
index 000000000000..74495401e153
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-64-fail.l
@@ -0,0 +1,9 @@
+.*: Assembler messages:
+.*: Error: illegal operands `amocas\.q a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.q a0,a5,\(a3\)'
+.*: Error: illegal operands `amocas\.q\.aq a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.q\.aq a0,a5,\(a3\)'
+.*: Error: illegal operands `amocas\.q\.rl a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.q\.rl a0,a5,\(a3\)'
+.*: Error: illegal operands `amocas\.q\.aqrl a1,a4,\(a3\)'
+.*: Error: illegal operands `amocas\.q\.aqrl a0,a5,\(a3\)'
diff --git a/gas/testsuite/gas/riscv/zacas-64-fail.s b/gas/testsuite/gas/riscv/zacas-64-fail.s
new file mode 100644
index 000000000000..96ee4a378bf5
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-64-fail.s
@@ -0,0 +1,10 @@
+target:
+	# amocas.q (RV64): rd (operand 1) and rs2 (operand 2) must be even.
+	amocas.q	a1, a4, (a3)
+	amocas.q	a0, a5, (a3)
+	amocas.q.aq	a1, a4, (a3)
+	amocas.q.aq	a0, a5, (a3)
+	amocas.q.rl	a1, a4, (a3)
+	amocas.q.rl	a0, a5, (a3)
+	amocas.q.aqrl	a1, a4, (a3)
+	amocas.q.aqrl	a0, a5, (a3)
diff --git a/gas/testsuite/gas/riscv/zacas-64.d b/gas/testsuite/gas/riscv/zacas-64.d
new file mode 100644
index 000000000000..027806aad4fc
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-64.d
@@ -0,0 +1,21 @@
+#as: -march=rv64i_zacas
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+28f6a5af[ 	]+amocas\.w[ 		]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2cf6a5af[ 	]+amocas\.w\.aq[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2af6a5af[ 	]+amocas\.w\.rl[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ef6a5af[ 	]+amocas\.w\.aqrl[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+28f6b5af[ 	]+amocas\.d[ 		]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2cf6b5af[ 	]+amocas\.d\.aq[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2af6b5af[ 	]+amocas\.d\.rl[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ef6b5af[ 	]+amocas\.d\.aqrl[ 	]+a1,a5,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+28e6c52f[ 	]+amocas\.q[ 		]+a0,a4,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ce6c52f[ 	]+amocas\.q\.aq[ 	]+a0,a4,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ae6c52f[ 	]+amocas\.q\.rl[ 	]+a0,a4,\(a3\)
+[ 	]+[0-9a-f]+:[ 	]+2ee6c52f[ 	]+amocas\.q\.aqrl[ 	]+a0,a4,\(a3\)
diff --git a/gas/testsuite/gas/riscv/zacas-64.s b/gas/testsuite/gas/riscv/zacas-64.s
new file mode 100644
index 000000000000..3b9f7a0bfc7e
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zacas-64.s
@@ -0,0 +1,13 @@
+target:
+	amocas.w	a1, a5, (a3)
+	amocas.w.aq	a1, a5, (a3)
+	amocas.w.rl	a1, a5, (a3)
+	amocas.w.aqrl	a1, a5, (a3)
+	amocas.d	a1, a5, (a3)
+	amocas.d.aq	a1, a5, (a3)
+	amocas.d.rl	a1, a5, (a3)
+	amocas.d.aqrl	a1, a5, (a3)
+	amocas.q	a0, a4, (a3)
+	amocas.q.aq	a0, a4, (a3)
+	amocas.q.rl	a0, a4, (a3)
+	amocas.q.aqrl	a0, a4, (a3)
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 375483500e2a..8fb59e3db93e 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -2315,6 +2315,13 @@
 #define MASK_C_NTL_S1 0xffff
 #define MATCH_C_NTL_ALL 0x9016
 #define MASK_C_NTL_ALL 0xffff
+/* Zacas instructions.  */
+#define MATCH_AMOCAS_D 0x2800302f
+#define MASK_AMOCAS_D 0xf800707f
+#define MATCH_AMOCAS_Q 0x2800402f
+#define MASK_AMOCAS_Q 0xf800707f
+#define MATCH_AMOCAS_W 0x2800202f
+#define MASK_AMOCAS_W 0xf800707f
 /* Zawrs instructions.  */
 #define MATCH_WRS_NTO 0x00d00073
 #define MASK_WRS_NTO 0xffffffff
@@ -3370,6 +3377,10 @@ DECLARE_INSN(c_ntl_p1, MATCH_C_NTL_P1, MASK_C_NTL_P1)
 DECLARE_INSN(c_ntl_pall, MATCH_C_NTL_PALL, MASK_C_NTL_PALL)
 DECLARE_INSN(c_ntl_s1, MATCH_C_NTL_S1, MASK_C_NTL_S1)
 DECLARE_INSN(c_ntl_all, MATCH_C_NTL_ALL, MASK_C_NTL_ALL)
+/* Zacas instructions.  */
+DECLARE_INSN(amocas_d, MATCH_AMOCAS_D, MASK_AMOCAS_D)
+DECLARE_INSN(amocas_q, MATCH_AMOCAS_Q, MASK_AMOCAS_Q)
+DECLARE_INSN(amocas_w, MATCH_AMOCAS_W, MASK_AMOCAS_W)
 /* Zawrs instructions.  */
 DECLARE_INSN(wrs_nto, MATCH_WRS_NTO, MASK_WRS_NTO)
 DECLARE_INSN(wrs_sto, MATCH_WRS_STO, MASK_WRS_STO)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 93dd5169ebce..aefbfc7db81e 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -396,6 +396,7 @@ enum riscv_insn_class
   INSN_CLASS_ZIHINTNTL_AND_C,
   INSN_CLASS_ZIHINTPAUSE,
   INSN_CLASS_ZMMUL,
+  INSN_CLASS_ZACAS,
   INSN_CLASS_ZAWRS,
   INSN_CLASS_F_INX,
   INSN_CLASS_D_INX,
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 8e0ae85eb064..58087ca19cac 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -290,6 +290,24 @@ match_vd_eq_vs1_eq_vs2 (const struct riscv_opcode *op,
   return match_opcode (op, insn) && vd == vs1 && vs1 == vs2;
 }
 
+/* Instructions with register groups.  */
+
+#define DEFINE_MATCH_FUNC_R(G_RD,G_RS1,G_RS2) \
+  static int \
+  match_reggroup_r_##G_RD##_##G_RS1##_##G_RS2 (const struct riscv_opcode *op, \
+					       insn_t insn) \
+  { \
+    int rd = (insn & MASK_RD) >> OP_SH_RD; \
+    int rs1 = (insn & MASK_RS1) >> OP_SH_RS1; \
+    int rs2 = (insn & MASK_RS2) >> OP_SH_RS2; \
+    return match_opcode (op, insn) \
+	   && (rd % G_RD == 0) \
+	   && (rs1 % G_RS1 == 0) \
+	   && (rs2 % G_RS2 == 0); \
+  }
+DEFINE_MATCH_FUNC_R(1, 1, 1)
+DEFINE_MATCH_FUNC_R(2, 1, 2)
+
 static int
 match_th_load_inc(const struct riscv_opcode *op,
 		  insn_t insn)
@@ -982,6 +1000,24 @@ const struct riscv_opcode riscv_opcodes[] =
 {"czero.eqz",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_EQZ, MASK_CZERO_EQZ, match_opcode, 0 },
 {"czero.nez",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_NEZ, MASK_CZERO_NEZ, match_opcode, 0 },
 
+/* Zacas instructions.  */
+{"amocas.w",       0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"amocas.w.aq",    0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W|MASK_AQ, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"amocas.w.rl",    0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W|MASK_RL, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"amocas.w.aqrl",  0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W|MASK_AQRL, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"amocas.d",      32, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_8_BYTE },
+{"amocas.d",      64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_1_1_1, INSN_DREF|INSN_8_BYTE },
+{"amocas.d.aq",   32, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_AQ, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_8_BYTE },
+{"amocas.d.aq",   64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_AQ, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_1_1_1, INSN_DREF|INSN_8_BYTE },
+{"amocas.d.rl",   32, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_RL, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_8_BYTE },
+{"amocas.d.rl",   64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_RL, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_1_1_1, INSN_DREF|INSN_8_BYTE },
+{"amocas.d.aqrl", 32, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_AQRL, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_8_BYTE },
+{"amocas.d.aqrl", 64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_AQRL, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_1_1_1, INSN_DREF|INSN_8_BYTE },
+{"amocas.q",      64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_Q, MASK_AMOCAS_Q|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_16_BYTE },
+{"amocas.q.aq",   64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_Q|MASK_AQ, MASK_AMOCAS_Q|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_16_BYTE },
+{"amocas.q.rl",   64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_Q|MASK_RL, MASK_AMOCAS_Q|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_16_BYTE },
+{"amocas.q.aqrl", 64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_Q|MASK_AQRL, MASK_AMOCAS_Q|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_16_BYTE },
+
 /* Zawrs instructions.  */
 {"wrs.nto",    0, INSN_CLASS_ZAWRS, "", MATCH_WRS_NTO, MASK_WRS_NTO, match_opcode, 0 },
 {"wrs.sto",    0, INSN_CLASS_ZAWRS, "", MATCH_WRS_STO, MASK_WRS_STO, match_opcode, 0 },

base-commit: d249c8a63aec45648b2165532f79b09763870795
-- 
2.42.0


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

* [REVIEW ONLY] UNRATIFIED RISC-V: Add support for 'Zabha' subword AMO extension
  2023-10-22  3:54 ` [PATCH v2] " Tsukasa OI
@ 2023-10-22  3:57   ` Tsukasa OI
  2023-10-22  3:59   ` [PATCH v2] RISC-V: Add support for 'Zacas' atomic CAS Tsukasa OI
  2023-10-23  6:47   ` Jan Beulich
  2 siblings, 0 replies; 11+ messages in thread
From: Tsukasa OI @ 2023-10-22  3:57 UTC (permalink / raw)
  To: Tsukasa OI; +Cc: binutils

From: Tsukasa OI <research_trasio@irq.a4lg.com>

[DEPENDENCY]
This patch requires my 'Zacas' support patch v2 as in:
<https://sourceware.org/pipermail/binutils/2023-October/130098.html>

[DO NOT MERGE]
Despite that this extension is nearing to be Frozen, the development of
this extension is not yet completed.
Until this extension is frozen/ratified and final version number is
determined, this patch should not be merged upstream. This commit uses
unratified version 0.9 as in the latest release tag:
<https://github.com/riscv/riscv-zabha/releases/tag/v0.9>

This commit adds support for the 'Zabha' extension, adding subword
(byte and half) AMO instructions.

This is based on the latest commit:
<https://github.com/riscv/riscv-zabha/commit/810f0ee06ef13d98549b88d1453bca8fb57dda0a>

bfd/ChangeLog:

	* elfxx-riscv.c
	(riscv_implicit_subsets): Make 'Zabha' to imply 'A' extension.
	(riscv_supported_std_z_ext): Add 'Zabha' to the supported list.
	(riscv_multi_subset_supports, riscv_multi_subset_supports_ext):
	Add handling for new instruction classes.

gas/ChangeLog:

	* testsuite/gas/riscv/zabha.s: New test.
	* testsuite/gas/riscv/zabha.d: Likewise.
	* testsuite/gas/riscv/zabha-zacas.s: New test.
	* testsuite/gas/riscv/zabha-zacas.d: Likewise.

include/ChangeLog:

	* opcode/riscv-opc.h (MATCH_AMOADD_B, MASK_AMOADD_B,
	MATCH_AMOADD_H, MASK_AMOADD_H, MATCH_AMOAND_B, MASK_AMOAND_B,
	MATCH_AMOAND_H, MASK_AMOAND_H, MATCH_AMOMAX_B, MASK_AMOMAX_B,
	MATCH_AMOMAX_H, MASK_AMOMAX_H, MATCH_AMOMAXU_B, MASK_AMOMAXU_B,
	MATCH_AMOMAXU_H, MASK_AMOMAXU_H, MATCH_AMOMIN_B, MASK_AMOMIN_B,
	MATCH_AMOMIN_H, MASK_AMOMIN_H, MATCH_AMOMINU_B, MASK_AMOMINU_B,
	MATCH_AMOMINU_H, MASK_AMOMINU_H, MATCH_AMOOR_B, MASK_AMOOR_B,
	MATCH_AMOOR_H, MASK_AMOOR_H, MATCH_AMOSWAP_B, MASK_AMOSWAP_B,
	MATCH_AMOSWAP_H, MASK_AMOSWAP_H, MATCH_AMOXOR_B, MASK_AMOXOR_B,
	MATCH_AMOXOR_H, MASK_AMOXOR_H, MATCH_AMOCAS_B, MASK_AMOCAS_B,
	MATCH_AMOCAS_H, MASK_AMOCAS_H): New.
	* opcode/riscv.h (enum riscv_insn_class): Add new instruction
	classes INSN_CLASS_ZABHA and INSN_CLASS_ZABHA_AND_ZACAS.

opcodes/ChangeLog:

	* riscv-opc.c (riscv_opcodes): Add subword AMO instructions.
---
 bfd/elfxx-riscv.c                     | 17 ++++++
 gas/testsuite/gas/riscv/zabha-zacas.d | 17 ++++++
 gas/testsuite/gas/riscv/zabha-zacas.s |  9 +++
 gas/testsuite/gas/riscv/zabha.d       | 81 ++++++++++++++++++++++++++
 gas/testsuite/gas/riscv/zabha.s       | 73 ++++++++++++++++++++++++
 include/opcode/riscv-opc.h            | 62 ++++++++++++++++++++
 include/opcode/riscv.h                |  2 +
 opcodes/riscv-opc.c                   | 82 +++++++++++++++++++++++++++
 8 files changed, 343 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/zabha-zacas.d
 create mode 100644 gas/testsuite/gas/riscv/zabha-zacas.s
 create mode 100644 gas/testsuite/gas/riscv/zabha.d
 create mode 100644 gas/testsuite/gas/riscv/zabha.s

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index b7e067794ba8..21fc99ef8c68 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1148,6 +1148,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"zhinx", "zhinxmin",	check_implicit_always},
   {"zhinxmin", "zfinx",	check_implicit_always},
   {"zfinx", "zicsr",	check_implicit_always},
+  {"zabha", "a",	check_implicit_always},
   {"zacas", "a",	check_implicit_always},
   {"zk", "zkn",		check_implicit_always},
   {"zk", "zkr",		check_implicit_always},
@@ -1260,6 +1261,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
   {"zihintntl",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zihintpause",	ISA_SPEC_CLASS_DRAFT,		2, 0,  0 },
   {"zmmul",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
+  {"zabha",		ISA_SPEC_CLASS_DRAFT,		0, 9,  0 },
   {"zacas",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zawrs",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zfa",		ISA_SPEC_CLASS_DRAFT,		0, 1,  0 },
@@ -2411,6 +2413,11 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return riscv_subset_supports (rps, "zmmul");
     case INSN_CLASS_A:
       return riscv_subset_supports (rps, "a");
+    case INSN_CLASS_ZABHA:
+      return riscv_subset_supports (rps, "zabha");
+    case INSN_CLASS_ZABHA_AND_ZACAS:
+      return (riscv_subset_supports (rps, "zabha")
+	      && riscv_subset_supports (rps, "zacas"));
     case INSN_CLASS_ZACAS:
       return riscv_subset_supports (rps, "zacas");
     case INSN_CLASS_ZAWRS:
@@ -2623,6 +2630,16 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return _ ("m' or `zmmul");
     case INSN_CLASS_A:
       return "a";
+    case INSN_CLASS_ZABHA:
+      return "zabha";
+    case INSN_CLASS_ZABHA_AND_ZACAS:
+      if (!riscv_subset_supports (rps, "zabha")
+	  && !riscv_subset_supports (rps, "zacas"))
+	return _("zabha' and `zacas");
+      else if (!riscv_subset_supports (rps, "zabha"))
+	return "zabha";
+      else
+	return "zacas";
     case INSN_CLASS_ZACAS:
       return "zacas";
     case INSN_CLASS_ZAWRS:
diff --git a/gas/testsuite/gas/riscv/zabha-zacas.d b/gas/testsuite/gas/riscv/zabha-zacas.d
new file mode 100644
index 000000000000..ea3657a6093c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zabha-zacas.d
@@ -0,0 +1,17 @@
+#as: -march=rv32i_zabha_zacas
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+28c5852f[ 	]+amocas\.b[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+2cc5852f[ 	]+amocas\.b\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+2ac5852f[ 	]+amocas\.b\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+2ec5852f[ 	]+amocas\.b\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+28c5952f[ 	]+amocas\.h[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+2cc5952f[ 	]+amocas\.h\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+2ac5952f[ 	]+amocas\.h\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+2ec5952f[ 	]+amocas\.h\.aqrl[ 	]+a0,a2,\(a1\)
diff --git a/gas/testsuite/gas/riscv/zabha-zacas.s b/gas/testsuite/gas/riscv/zabha-zacas.s
new file mode 100644
index 000000000000..09aac3b94018
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zabha-zacas.s
@@ -0,0 +1,9 @@
+target:
+	amocas.b	a0, a2, (a1)
+	amocas.b.aq	a0, a2, (a1)
+	amocas.b.rl	a0, a2, (a1)
+	amocas.b.aqrl	a0, a2, (a1)
+	amocas.h	a0, a2, (a1)
+	amocas.h.aq	a0, a2, (a1)
+	amocas.h.rl	a0, a2, (a1)
+	amocas.h.aqrl	a0, a2, (a1)
diff --git a/gas/testsuite/gas/riscv/zabha.d b/gas/testsuite/gas/riscv/zabha.d
new file mode 100644
index 000000000000..0cc39f9da821
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zabha.d
@@ -0,0 +1,81 @@
+#as: -march=rv32i_zabha
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+08c5852f[ 	]+amoswap\.b[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+0cc5852f[ 	]+amoswap\.b\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+0ac5852f[ 	]+amoswap\.b\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+0ec5852f[ 	]+amoswap\.b\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+00c5852f[ 	]+amoadd\.b[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+04c5852f[ 	]+amoadd\.b\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+02c5852f[ 	]+amoadd\.b\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+06c5852f[ 	]+amoadd\.b\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+20c5852f[ 	]+amoxor\.b[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+24c5852f[ 	]+amoxor\.b\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+22c5852f[ 	]+amoxor\.b\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+26c5852f[ 	]+amoxor\.b\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+60c5852f[ 	]+amoand\.b[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+64c5852f[ 	]+amoand\.b\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+62c5852f[ 	]+amoand\.b\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+66c5852f[ 	]+amoand\.b\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+40c5852f[ 	]+amoor\.b[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+44c5852f[ 	]+amoor\.b\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+42c5852f[ 	]+amoor\.b\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+46c5852f[ 	]+amoor\.b\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+80c5852f[ 	]+amomin\.b[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+84c5852f[ 	]+amomin\.b\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+82c5852f[ 	]+amomin\.b\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+86c5852f[ 	]+amomin\.b\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+a0c5852f[ 	]+amomax\.b[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+a4c5852f[ 	]+amomax\.b\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+a2c5852f[ 	]+amomax\.b\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+a6c5852f[ 	]+amomax\.b\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+c0c5852f[ 	]+amominu\.b[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+c4c5852f[ 	]+amominu\.b\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+c2c5852f[ 	]+amominu\.b\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+c6c5852f[ 	]+amominu\.b\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+e0c5852f[ 	]+amomaxu\.b[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+e4c5852f[ 	]+amomaxu\.b\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+e2c5852f[ 	]+amomaxu\.b\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+e6c5852f[ 	]+amomaxu\.b\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+08c5952f[ 	]+amoswap\.h[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+0cc5952f[ 	]+amoswap\.h\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+0ac5952f[ 	]+amoswap\.h\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+0ec5952f[ 	]+amoswap\.h\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+00c5952f[ 	]+amoadd\.h[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+04c5952f[ 	]+amoadd\.h\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+02c5952f[ 	]+amoadd\.h\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+06c5952f[ 	]+amoadd\.h\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+20c5952f[ 	]+amoxor\.h[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+24c5952f[ 	]+amoxor\.h\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+22c5952f[ 	]+amoxor\.h\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+26c5952f[ 	]+amoxor\.h\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+60c5952f[ 	]+amoand\.h[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+64c5952f[ 	]+amoand\.h\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+62c5952f[ 	]+amoand\.h\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+66c5952f[ 	]+amoand\.h\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+40c5952f[ 	]+amoor\.h[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+44c5952f[ 	]+amoor\.h\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+42c5952f[ 	]+amoor\.h\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+46c5952f[ 	]+amoor\.h\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+80c5952f[ 	]+amomin\.h[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+84c5952f[ 	]+amomin\.h\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+82c5952f[ 	]+amomin\.h\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+86c5952f[ 	]+amomin\.h\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+a0c5952f[ 	]+amomax\.h[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+a4c5952f[ 	]+amomax\.h\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+a2c5952f[ 	]+amomax\.h\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+a6c5952f[ 	]+amomax\.h\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+c0c5952f[ 	]+amominu\.h[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+c4c5952f[ 	]+amominu\.h\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+c2c5952f[ 	]+amominu\.h\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+c6c5952f[ 	]+amominu\.h\.aqrl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+e0c5952f[ 	]+amomaxu\.h[ 		]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+e4c5952f[ 	]+amomaxu\.h\.aq[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+e2c5952f[ 	]+amomaxu\.h\.rl[ 	]+a0,a2,\(a1\)
+[ 	]+[0-9a-f]+:[ 	]+e6c5952f[ 	]+amomaxu\.h\.aqrl[ 	]+a0,a2,\(a1\)
diff --git a/gas/testsuite/gas/riscv/zabha.s b/gas/testsuite/gas/riscv/zabha.s
new file mode 100644
index 000000000000..ab521119a75e
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zabha.s
@@ -0,0 +1,73 @@
+target:
+	amoswap.b	a0, a2, (a1)
+	amoswap.b.aq	a0, a2, (a1)
+	amoswap.b.rl	a0, a2, (a1)
+	amoswap.b.aqrl	a0, a2, (a1)
+	amoadd.b	a0, a2, (a1)
+	amoadd.b.aq	a0, a2, (a1)
+	amoadd.b.rl	a0, a2, (a1)
+	amoadd.b.aqrl	a0, a2, (a1)
+	amoxor.b	a0, a2, (a1)
+	amoxor.b.aq	a0, a2, (a1)
+	amoxor.b.rl	a0, a2, (a1)
+	amoxor.b.aqrl	a0, a2, (a1)
+	amoand.b	a0, a2, (a1)
+	amoand.b.aq	a0, a2, (a1)
+	amoand.b.rl	a0, a2, (a1)
+	amoand.b.aqrl	a0, a2, (a1)
+	amoor.b		a0, a2, (a1)
+	amoor.b.aq	a0, a2, (a1)
+	amoor.b.rl	a0, a2, (a1)
+	amoor.b.aqrl	a0, a2, (a1)
+	amomin.b	a0, a2, (a1)
+	amomin.b.aq	a0, a2, (a1)
+	amomin.b.rl	a0, a2, (a1)
+	amomin.b.aqrl	a0, a2, (a1)
+	amomax.b	a0, a2, (a1)
+	amomax.b.aq	a0, a2, (a1)
+	amomax.b.rl	a0, a2, (a1)
+	amomax.b.aqrl	a0, a2, (a1)
+	amominu.b	a0, a2, (a1)
+	amominu.b.aq	a0, a2, (a1)
+	amominu.b.rl	a0, a2, (a1)
+	amominu.b.aqrl	a0, a2, (a1)
+	amomaxu.b	a0, a2, (a1)
+	amomaxu.b.aq	a0, a2, (a1)
+	amomaxu.b.rl	a0, a2, (a1)
+	amomaxu.b.aqrl	a0, a2, (a1)
+	amoswap.h	a0, a2, (a1)
+	amoswap.h.aq	a0, a2, (a1)
+	amoswap.h.rl	a0, a2, (a1)
+	amoswap.h.aqrl	a0, a2, (a1)
+	amoadd.h	a0, a2, (a1)
+	amoadd.h.aq	a0, a2, (a1)
+	amoadd.h.rl	a0, a2, (a1)
+	amoadd.h.aqrl	a0, a2, (a1)
+	amoxor.h	a0, a2, (a1)
+	amoxor.h.aq	a0, a2, (a1)
+	amoxor.h.rl	a0, a2, (a1)
+	amoxor.h.aqrl	a0, a2, (a1)
+	amoand.h	a0, a2, (a1)
+	amoand.h.aq	a0, a2, (a1)
+	amoand.h.rl	a0, a2, (a1)
+	amoand.h.aqrl	a0, a2, (a1)
+	amoor.h		a0, a2, (a1)
+	amoor.h.aq	a0, a2, (a1)
+	amoor.h.rl	a0, a2, (a1)
+	amoor.h.aqrl	a0, a2, (a1)
+	amomin.h	a0, a2, (a1)
+	amomin.h.aq	a0, a2, (a1)
+	amomin.h.rl	a0, a2, (a1)
+	amomin.h.aqrl	a0, a2, (a1)
+	amomax.h	a0, a2, (a1)
+	amomax.h.aq	a0, a2, (a1)
+	amomax.h.rl	a0, a2, (a1)
+	amomax.h.aqrl	a0, a2, (a1)
+	amominu.h	a0, a2, (a1)
+	amominu.h.aq	a0, a2, (a1)
+	amominu.h.rl	a0, a2, (a1)
+	amominu.h.aqrl	a0, a2, (a1)
+	amomaxu.h	a0, a2, (a1)
+	amomaxu.h.aq	a0, a2, (a1)
+	amomaxu.h.rl	a0, a2, (a1)
+	amomaxu.h.aqrl	a0, a2, (a1)
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 8fb59e3db93e..49786513a0ab 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -2315,6 +2315,47 @@
 #define MASK_C_NTL_S1 0xffff
 #define MATCH_C_NTL_ALL 0x9016
 #define MASK_C_NTL_ALL 0xffff
+/* Zabha instructions.  */
+#define MATCH_AMOADD_B 0x2f
+#define MASK_AMOADD_B 0xf800707f
+#define MATCH_AMOADD_H 0x102f
+#define MASK_AMOADD_H 0xf800707f
+#define MATCH_AMOAND_B 0x6000002f
+#define MASK_AMOAND_B 0xf800707f
+#define MATCH_AMOAND_H 0x6000102f
+#define MASK_AMOAND_H 0xf800707f
+#define MATCH_AMOMAX_B 0xa000002f
+#define MASK_AMOMAX_B 0xf800707f
+#define MATCH_AMOMAX_H 0xa000102f
+#define MASK_AMOMAX_H 0xf800707f
+#define MATCH_AMOMAXU_B 0xe000002f
+#define MASK_AMOMAXU_B 0xf800707f
+#define MATCH_AMOMAXU_H 0xe000102f
+#define MASK_AMOMAXU_H 0xf800707f
+#define MATCH_AMOMIN_B 0x8000002f
+#define MASK_AMOMIN_B 0xf800707f
+#define MATCH_AMOMIN_H 0x8000102f
+#define MASK_AMOMIN_H 0xf800707f
+#define MATCH_AMOMINU_B 0xc000002f
+#define MASK_AMOMINU_B 0xf800707f
+#define MATCH_AMOMINU_H 0xc000102f
+#define MASK_AMOMINU_H 0xf800707f
+#define MATCH_AMOOR_B 0x4000002f
+#define MASK_AMOOR_B 0xf800707f
+#define MATCH_AMOOR_H 0x4000102f
+#define MASK_AMOOR_H 0xf800707f
+#define MATCH_AMOSWAP_B 0x800002f
+#define MASK_AMOSWAP_B 0xf800707f
+#define MATCH_AMOSWAP_H 0x800102f
+#define MASK_AMOSWAP_H 0xf800707f
+#define MATCH_AMOXOR_B 0x2000002f
+#define MASK_AMOXOR_B 0xf800707f
+#define MATCH_AMOXOR_H 0x2000102f
+#define MASK_AMOXOR_H 0xf800707f
+#define MATCH_AMOCAS_B 0x2800002f
+#define MASK_AMOCAS_B 0xf800707f
+#define MATCH_AMOCAS_H 0x2800102f
+#define MASK_AMOCAS_H 0xf800707f
 /* Zacas instructions.  */
 #define MATCH_AMOCAS_D 0x2800302f
 #define MASK_AMOCAS_D 0xf800707f
@@ -3377,6 +3418,27 @@ DECLARE_INSN(c_ntl_p1, MATCH_C_NTL_P1, MASK_C_NTL_P1)
 DECLARE_INSN(c_ntl_pall, MATCH_C_NTL_PALL, MASK_C_NTL_PALL)
 DECLARE_INSN(c_ntl_s1, MATCH_C_NTL_S1, MASK_C_NTL_S1)
 DECLARE_INSN(c_ntl_all, MATCH_C_NTL_ALL, MASK_C_NTL_ALL)
+/* Zabha instructions.  */
+DECLARE_INSN(amoadd_b, MATCH_AMOADD_B, MASK_AMOADD_B)
+DECLARE_INSN(amoadd_h, MATCH_AMOADD_H, MASK_AMOADD_H)
+DECLARE_INSN(amoand_b, MATCH_AMOAND_B, MASK_AMOAND_B)
+DECLARE_INSN(amoand_h, MATCH_AMOAND_H, MASK_AMOAND_H)
+DECLARE_INSN(amomax_b, MATCH_AMOMAX_B, MASK_AMOMAX_B)
+DECLARE_INSN(amomax_h, MATCH_AMOMAX_H, MASK_AMOMAX_H)
+DECLARE_INSN(amomaxu_b, MATCH_AMOMAXU_B, MASK_AMOMAXU_B)
+DECLARE_INSN(amomaxu_h, MATCH_AMOMAXU_H, MASK_AMOMAXU_H)
+DECLARE_INSN(amomin_b, MATCH_AMOMIN_B, MASK_AMOMIN_B)
+DECLARE_INSN(amomin_h, MATCH_AMOMIN_H, MASK_AMOMIN_H)
+DECLARE_INSN(amominu_b, MATCH_AMOMINU_B, MASK_AMOMINU_B)
+DECLARE_INSN(amominu_h, MATCH_AMOMINU_H, MASK_AMOMINU_H)
+DECLARE_INSN(amoor_b, MATCH_AMOOR_B, MASK_AMOOR_B)
+DECLARE_INSN(amoor_h, MATCH_AMOOR_H, MASK_AMOOR_H)
+DECLARE_INSN(amoswap_b, MATCH_AMOSWAP_B, MASK_AMOSWAP_B)
+DECLARE_INSN(amoswap_h, MATCH_AMOSWAP_H, MASK_AMOSWAP_H)
+DECLARE_INSN(amoxor_b, MATCH_AMOXOR_B, MASK_AMOXOR_B)
+DECLARE_INSN(amoxor_h, MATCH_AMOXOR_H, MASK_AMOXOR_H)
+DECLARE_INSN(amocas_b, MATCH_AMOCAS_B, MASK_AMOCAS_B)
+DECLARE_INSN(amocas_h, MATCH_AMOCAS_H, MASK_AMOCAS_H)
 /* Zacas instructions.  */
 DECLARE_INSN(amocas_d, MATCH_AMOCAS_D, MASK_AMOCAS_D)
 DECLARE_INSN(amocas_q, MATCH_AMOCAS_Q, MASK_AMOCAS_Q)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index aefbfc7db81e..f22f89bc38bd 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -396,6 +396,8 @@ enum riscv_insn_class
   INSN_CLASS_ZIHINTNTL_AND_C,
   INSN_CLASS_ZIHINTPAUSE,
   INSN_CLASS_ZMMUL,
+  INSN_CLASS_ZABHA,
+  INSN_CLASS_ZABHA_AND_ZACAS,
   INSN_CLASS_ZACAS,
   INSN_CLASS_ZAWRS,
   INSN_CLASS_F_INX,
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 58087ca19cac..5955092d6f70 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -1000,6 +1000,88 @@ const struct riscv_opcode riscv_opcodes[] =
 {"czero.eqz",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_EQZ, MASK_CZERO_EQZ, match_opcode, 0 },
 {"czero.nez",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_NEZ, MASK_CZERO_NEZ, match_opcode, 0 },
 
+/* Zabha instructions.  */
+{"amoadd.b",        0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOADD_B, MASK_AMOADD_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoswap.b",       0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOSWAP_B, MASK_AMOSWAP_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoand.b",        0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOAND_B, MASK_AMOAND_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoor.b",         0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOOR_B, MASK_AMOOR_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoxor.b",        0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOXOR_B, MASK_AMOXOR_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amomax.b",        0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAX_B, MASK_AMOMAX_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amomaxu.b",       0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAXU_B, MASK_AMOMAXU_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amomin.b",        0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMIN_B, MASK_AMOMIN_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amominu.b",       0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMINU_B, MASK_AMOMINU_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoadd.b.aq",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOADD_B|MASK_AQ, MASK_AMOADD_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoswap.b.aq",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOSWAP_B|MASK_AQ, MASK_AMOSWAP_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoand.b.aq",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOAND_B|MASK_AQ, MASK_AMOAND_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoor.b.aq",      0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOOR_B|MASK_AQ, MASK_AMOOR_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoxor.b.aq",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOXOR_B|MASK_AQ, MASK_AMOXOR_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amomax.b.aq",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAX_B|MASK_AQ, MASK_AMOMAX_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amomaxu.b.aq",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAXU_B|MASK_AQ, MASK_AMOMAXU_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amomin.b.aq",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMIN_B|MASK_AQ, MASK_AMOMIN_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amominu.b.aq",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMINU_B|MASK_AQ, MASK_AMOMINU_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoadd.b.rl",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOADD_B|MASK_RL, MASK_AMOADD_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoswap.b.rl",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOSWAP_B|MASK_RL, MASK_AMOSWAP_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoand.b.rl",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOAND_B|MASK_RL, MASK_AMOAND_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoor.b.rl",      0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOOR_B|MASK_RL, MASK_AMOOR_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoxor.b.rl",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOXOR_B|MASK_RL, MASK_AMOXOR_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amomax.b.rl",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAX_B|MASK_RL, MASK_AMOMAX_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amomaxu.b.rl",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAXU_B|MASK_RL, MASK_AMOMAXU_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amomin.b.rl",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMIN_B|MASK_RL, MASK_AMOMIN_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amominu.b.rl",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMINU_B|MASK_RL, MASK_AMOMINU_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoadd.b.aqrl",   0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOADD_B|MASK_AQRL, MASK_AMOADD_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoswap.b.aqrl",  0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOSWAP_B|MASK_AQRL, MASK_AMOSWAP_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoand.b.aqrl",   0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOAND_B|MASK_AQRL, MASK_AMOAND_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoor.b.aqrl",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOOR_B|MASK_AQRL, MASK_AMOOR_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoxor.b.aqrl",   0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOXOR_B|MASK_AQRL, MASK_AMOXOR_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amomax.b.aqrl",   0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAX_B|MASK_AQRL, MASK_AMOMAX_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amomaxu.b.aqrl",  0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAXU_B|MASK_AQRL, MASK_AMOMAXU_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amomin.b.aqrl",   0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMIN_B|MASK_AQRL, MASK_AMOMIN_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amominu.b.aqrl",  0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMINU_B|MASK_AQRL, MASK_AMOMINU_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amoadd.h",        0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOADD_H, MASK_AMOADD_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoswap.h",       0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOSWAP_H, MASK_AMOSWAP_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoand.h",        0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOAND_H, MASK_AMOAND_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoor.h",         0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOOR_H, MASK_AMOOR_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoxor.h",        0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOXOR_H, MASK_AMOXOR_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amomax.h",        0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAX_H, MASK_AMOMAX_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amomaxu.h",       0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAXU_H, MASK_AMOMAXU_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amomin.h",        0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMIN_H, MASK_AMOMIN_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amominu.h",       0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMINU_H, MASK_AMOMINU_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoadd.h.aq",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOADD_H|MASK_AQ, MASK_AMOADD_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoswap.h.aq",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOSWAP_H|MASK_AQ, MASK_AMOSWAP_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoand.h.aq",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOAND_H|MASK_AQ, MASK_AMOAND_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoor.h.aq",      0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOOR_H|MASK_AQ, MASK_AMOOR_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoxor.h.aq",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOXOR_H|MASK_AQ, MASK_AMOXOR_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amomax.h.aq",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAX_H|MASK_AQ, MASK_AMOMAX_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amomaxu.h.aq",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAXU_H|MASK_AQ, MASK_AMOMAXU_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amomin.h.aq",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMIN_H|MASK_AQ, MASK_AMOMIN_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amominu.h.aq",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMINU_H|MASK_AQ, MASK_AMOMINU_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoadd.h.rl",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOADD_H|MASK_RL, MASK_AMOADD_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoswap.h.rl",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOSWAP_H|MASK_RL, MASK_AMOSWAP_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoand.h.rl",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOAND_H|MASK_RL, MASK_AMOAND_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoor.h.rl",      0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOOR_H|MASK_RL, MASK_AMOOR_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoxor.h.rl",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOXOR_H|MASK_RL, MASK_AMOXOR_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amomax.h.rl",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAX_H|MASK_RL, MASK_AMOMAX_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amomaxu.h.rl",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAXU_H|MASK_RL, MASK_AMOMAXU_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amomin.h.rl",     0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMIN_H|MASK_RL, MASK_AMOMIN_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amominu.h.rl",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMINU_H|MASK_RL, MASK_AMOMINU_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoadd.h.aqrl",   0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOADD_H|MASK_AQRL, MASK_AMOADD_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoswap.h.aqrl",  0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOSWAP_H|MASK_AQRL, MASK_AMOSWAP_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoand.h.aqrl",   0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOAND_H|MASK_AQRL, MASK_AMOAND_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoor.h.aqrl",    0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOOR_H|MASK_AQRL, MASK_AMOOR_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amoxor.h.aqrl",   0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOXOR_H|MASK_AQRL, MASK_AMOXOR_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amomax.h.aqrl",   0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAX_H|MASK_AQRL, MASK_AMOMAX_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amomaxu.h.aqrl",  0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMAXU_H|MASK_AQRL, MASK_AMOMAXU_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amomin.h.aqrl",   0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMIN_H|MASK_AQRL, MASK_AMOMIN_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amominu.h.aqrl",  0, INSN_CLASS_ZABHA, "d,t,0(s)", MATCH_AMOMINU_H|MASK_AQRL, MASK_AMOMINU_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amocas.b",        0, INSN_CLASS_ZABHA_AND_ZACAS, "d,t,0(s)", MATCH_AMOCAS_B, MASK_AMOCAS_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amocas.h",        0, INSN_CLASS_ZABHA_AND_ZACAS, "d,t,0(s)", MATCH_AMOCAS_H, MASK_AMOCAS_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amocas.b.aq",     0, INSN_CLASS_ZABHA_AND_ZACAS, "d,t,0(s)", MATCH_AMOCAS_B|MASK_AQ, MASK_AMOCAS_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amocas.h.aq",     0, INSN_CLASS_ZABHA_AND_ZACAS, "d,t,0(s)", MATCH_AMOCAS_H|MASK_AQ, MASK_AMOCAS_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amocas.b.rl",     0, INSN_CLASS_ZABHA_AND_ZACAS, "d,t,0(s)", MATCH_AMOCAS_B|MASK_RL, MASK_AMOCAS_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amocas.h.rl",     0, INSN_CLASS_ZABHA_AND_ZACAS, "d,t,0(s)", MATCH_AMOCAS_H|MASK_RL, MASK_AMOCAS_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+{"amocas.b.aqrl",   0, INSN_CLASS_ZABHA_AND_ZACAS, "d,t,0(s)", MATCH_AMOCAS_B|MASK_AQRL, MASK_AMOCAS_B|MASK_AQRL, match_opcode, INSN_DREF|INSN_1_BYTE },
+{"amocas.h.aqrl",   0, INSN_CLASS_ZABHA_AND_ZACAS, "d,t,0(s)", MATCH_AMOCAS_H|MASK_AQRL, MASK_AMOCAS_H|MASK_AQRL, match_opcode, INSN_DREF|INSN_2_BYTE },
+
 /* Zacas instructions.  */
 {"amocas.w",       0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
 {"amocas.w.aq",    0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W|MASK_AQ, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },

base-commit: d249c8a63aec45648b2165532f79b09763870795
prerequisite-patch-id: f193a410c915c5a76a424c9401bbf1ed6fb17164
-- 
2.42.0


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

* Re: [PATCH v2] RISC-V: Add support for 'Zacas' atomic CAS
  2023-10-22  3:54 ` [PATCH v2] " Tsukasa OI
  2023-10-22  3:57   ` [REVIEW ONLY] UNRATIFIED RISC-V: Add support for 'Zabha' subword AMO extension Tsukasa OI
@ 2023-10-22  3:59   ` Tsukasa OI
  2023-10-23  6:47   ` Jan Beulich
  2 siblings, 0 replies; 11+ messages in thread
From: Tsukasa OI @ 2023-10-22  3:59 UTC (permalink / raw)
  To: Binutils

Changes: v1 -> v2

1.  Added amocas.w* tests on RV64 (just because I forgot it)


That's it!

On 2023/10/22 12:54, Tsukasa OI wrote:
> From: Tsukasa OI <research_trasio@irq.a4lg.com>
> 
> This commit adds support for the 'Zacas' extension, adding atomic CAS
> instructions.  Beware that this extension also introduces the concept of
> register pairs and it checks the validity of rs1 and rs2 if applicable.
> 
> This is based on the latest (frozen) draft:
> <https://github.com/riscv/riscv-zacas/releases/tag/v1.0-rc5>
> 
> bfd/ChangeLog:
> 
> 	* elfxx-riscv.c
> 	(riscv_implicit_subsets): Make 'Zacas' to imply 'A' extension.
> 	(riscv_supported_std_z_ext): Add 'Zacas' to the supported list.
> 	(riscv_multi_subset_supports, riscv_multi_subset_supports_ext):
> 	Add handling for new instruction class.
> 
> gas/ChangeLog:
> 
> 	* testsuite/gas/riscv/zacas-32.s: New test.
> 	* testsuite/gas/riscv/zacas-32.d: Likewise.
> 	* testsuite/gas/riscv/zacas-64.s: Likewise.
> 	* testsuite/gas/riscv/zacas-64.d: Likewise.
> 	* testsuite/gas/riscv/zacas-32-fail.s: New failure test.
> 	* testsuite/gas/riscv/zacas-32-fail.d: Likewise.
> 	* testsuite/gas/riscv/zacas-32-fail.l: Likewise.
> 	* testsuite/gas/riscv/zacas-64-fail.s: New failure test.
> 	* testsuite/gas/riscv/zacas-64-fail.d: Likewise.
> 	* testsuite/gas/riscv/zacas-64-fail.l: Likewise.
> 
> include/ChangeLog:
> 
> 	* opcode/riscv-opc.h (MATCH_AMOCAS_D, MASK_AMOCAS_D,
> 	MATCH_AMOCAS_Q, MASK_AMOCAS_Q, MATCH_AMOCAS_W,
> 	MASK_AMOCAS_W): New.
> 	* opcode/riscv.h (enum riscv_insn_class): Add new instruction
> 	class INSN_CLASS_ZACAS.
> 
> opcodes/ChangeLog:
> 
> 	* riscv-opc.c (REGGROUP_REGS_x, REGGROUP_REGS_1, REGGROUP_REGS_2,
> 	DEFINE_MATCH_FUNC_R): New match function template with register
> 	groups.
> 	(match_reggroup_r_1_1_1, match_reggroup_r_1_2_2): New.
> 	(riscv_opcodes): Add atomic CAS instructions.
> ---
>  bfd/elfxx-riscv.c                       |  6 +++++
>  gas/testsuite/gas/riscv/zacas-32-fail.d |  2 ++
>  gas/testsuite/gas/riscv/zacas-32-fail.l |  9 +++++++
>  gas/testsuite/gas/riscv/zacas-32-fail.s | 10 +++++++
>  gas/testsuite/gas/riscv/zacas-32.d      | 17 ++++++++++++
>  gas/testsuite/gas/riscv/zacas-32.s      |  9 +++++++
>  gas/testsuite/gas/riscv/zacas-64-fail.d |  2 ++
>  gas/testsuite/gas/riscv/zacas-64-fail.l |  9 +++++++
>  gas/testsuite/gas/riscv/zacas-64-fail.s | 10 +++++++
>  gas/testsuite/gas/riscv/zacas-64.d      | 21 +++++++++++++++
>  gas/testsuite/gas/riscv/zacas-64.s      | 13 +++++++++
>  include/opcode/riscv-opc.h              | 11 ++++++++
>  include/opcode/riscv.h                  |  1 +
>  opcodes/riscv-opc.c                     | 36 +++++++++++++++++++++++++
>  14 files changed, 156 insertions(+)
>  create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.d
>  create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.l
>  create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.s
>  create mode 100644 gas/testsuite/gas/riscv/zacas-32.d
>  create mode 100644 gas/testsuite/gas/riscv/zacas-32.s
>  create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.d
>  create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.l
>  create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.s
>  create mode 100644 gas/testsuite/gas/riscv/zacas-64.d
>  create mode 100644 gas/testsuite/gas/riscv/zacas-64.s
> 
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index c070394a3667..b7e067794ba8 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1148,6 +1148,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
>    {"zhinx", "zhinxmin",	check_implicit_always},
>    {"zhinxmin", "zfinx",	check_implicit_always},
>    {"zfinx", "zicsr",	check_implicit_always},
> +  {"zacas", "a",	check_implicit_always},
>    {"zk", "zkn",		check_implicit_always},
>    {"zk", "zkr",		check_implicit_always},
>    {"zk", "zkt",		check_implicit_always},
> @@ -1259,6 +1260,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
>    {"zihintntl",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
>    {"zihintpause",	ISA_SPEC_CLASS_DRAFT,		2, 0,  0 },
>    {"zmmul",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
> +  {"zacas",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
>    {"zawrs",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
>    {"zfa",		ISA_SPEC_CLASS_DRAFT,		0, 1,  0 },
>    {"zfh",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
> @@ -2409,6 +2411,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
>        return riscv_subset_supports (rps, "zmmul");
>      case INSN_CLASS_A:
>        return riscv_subset_supports (rps, "a");
> +    case INSN_CLASS_ZACAS:
> +      return riscv_subset_supports (rps, "zacas");
>      case INSN_CLASS_ZAWRS:
>        return riscv_subset_supports (rps, "zawrs");
>      case INSN_CLASS_F:
> @@ -2619,6 +2623,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
>        return _ ("m' or `zmmul");
>      case INSN_CLASS_A:
>        return "a";
> +    case INSN_CLASS_ZACAS:
> +      return "zacas";
>      case INSN_CLASS_ZAWRS:
>        return "zawrs";
>      case INSN_CLASS_F:
> diff --git a/gas/testsuite/gas/riscv/zacas-32-fail.d b/gas/testsuite/gas/riscv/zacas-32-fail.d
> new file mode 100644
> index 000000000000..12c1bd90ac86
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-32-fail.d
> @@ -0,0 +1,2 @@
> +#as: -march=rv32i_zacas
> +#error_output: zacas-32-fail.l
> diff --git a/gas/testsuite/gas/riscv/zacas-32-fail.l b/gas/testsuite/gas/riscv/zacas-32-fail.l
> new file mode 100644
> index 000000000000..944a66ba7806
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-32-fail.l
> @@ -0,0 +1,9 @@
> +.*: Assembler messages:
> +.*: Error: illegal operands `amocas\.d a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.d a0,a5,\(a3\)'
> +.*: Error: illegal operands `amocas\.d\.aq a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.d\.aq a0,a5,\(a3\)'
> +.*: Error: illegal operands `amocas\.d\.rl a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.d\.rl a0,a5,\(a3\)'
> +.*: Error: illegal operands `amocas\.d\.aqrl a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.d\.aqrl a0,a5,\(a3\)'
> diff --git a/gas/testsuite/gas/riscv/zacas-32-fail.s b/gas/testsuite/gas/riscv/zacas-32-fail.s
> new file mode 100644
> index 000000000000..650ea1d8b6f2
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-32-fail.s
> @@ -0,0 +1,10 @@
> +target:
> +	# amocas.d (RV32): rd (operand 1) and rs2 (operand 2) must be even.
> +	amocas.d	a1, a4, (a3)
> +	amocas.d	a0, a5, (a3)
> +	amocas.d.aq	a1, a4, (a3)
> +	amocas.d.aq	a0, a5, (a3)
> +	amocas.d.rl	a1, a4, (a3)
> +	amocas.d.rl	a0, a5, (a3)
> +	amocas.d.aqrl	a1, a4, (a3)
> +	amocas.d.aqrl	a0, a5, (a3)
> diff --git a/gas/testsuite/gas/riscv/zacas-32.d b/gas/testsuite/gas/riscv/zacas-32.d
> new file mode 100644
> index 000000000000..60f4fe09f866
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-32.d
> @@ -0,0 +1,17 @@
> +#as: -march=rv32i_zacas
> +#objdump: -d
> +
> +.*:[ 	]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <target>:
> +[ 	]+[0-9a-f]+:[ 	]+28f6a5af[ 	]+amocas\.w[ 		]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2cf6a5af[ 	]+amocas\.w\.aq[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2af6a5af[ 	]+amocas\.w\.rl[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ef6a5af[ 	]+amocas\.w\.aqrl[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+28e6b52f[ 	]+amocas\.d[ 		]+a0,a4,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ce6b52f[ 	]+amocas\.d\.aq[ 	]+a0,a4,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ae6b52f[ 	]+amocas\.d\.rl[ 	]+a0,a4,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ee6b52f[ 	]+amocas\.d\.aqrl[ 	]+a0,a4,\(a3\)
> diff --git a/gas/testsuite/gas/riscv/zacas-32.s b/gas/testsuite/gas/riscv/zacas-32.s
> new file mode 100644
> index 000000000000..c12c0e42f338
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-32.s
> @@ -0,0 +1,9 @@
> +target:
> +	amocas.w	a1, a5, (a3)
> +	amocas.w.aq	a1, a5, (a3)
> +	amocas.w.rl	a1, a5, (a3)
> +	amocas.w.aqrl	a1, a5, (a3)
> +	amocas.d	a0, a4, (a3)
> +	amocas.d.aq	a0, a4, (a3)
> +	amocas.d.rl	a0, a4, (a3)
> +	amocas.d.aqrl	a0, a4, (a3)
> diff --git a/gas/testsuite/gas/riscv/zacas-64-fail.d b/gas/testsuite/gas/riscv/zacas-64-fail.d
> new file mode 100644
> index 000000000000..e1910d81f9e2
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-64-fail.d
> @@ -0,0 +1,2 @@
> +#as: -march=rv64i_zacas
> +#error_output: zacas-64-fail.l
> diff --git a/gas/testsuite/gas/riscv/zacas-64-fail.l b/gas/testsuite/gas/riscv/zacas-64-fail.l
> new file mode 100644
> index 000000000000..74495401e153
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-64-fail.l
> @@ -0,0 +1,9 @@
> +.*: Assembler messages:
> +.*: Error: illegal operands `amocas\.q a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.q a0,a5,\(a3\)'
> +.*: Error: illegal operands `amocas\.q\.aq a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.q\.aq a0,a5,\(a3\)'
> +.*: Error: illegal operands `amocas\.q\.rl a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.q\.rl a0,a5,\(a3\)'
> +.*: Error: illegal operands `amocas\.q\.aqrl a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.q\.aqrl a0,a5,\(a3\)'
> diff --git a/gas/testsuite/gas/riscv/zacas-64-fail.s b/gas/testsuite/gas/riscv/zacas-64-fail.s
> new file mode 100644
> index 000000000000..96ee4a378bf5
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-64-fail.s
> @@ -0,0 +1,10 @@
> +target:
> +	# amocas.q (RV64): rd (operand 1) and rs2 (operand 2) must be even.
> +	amocas.q	a1, a4, (a3)
> +	amocas.q	a0, a5, (a3)
> +	amocas.q.aq	a1, a4, (a3)
> +	amocas.q.aq	a0, a5, (a3)
> +	amocas.q.rl	a1, a4, (a3)
> +	amocas.q.rl	a0, a5, (a3)
> +	amocas.q.aqrl	a1, a4, (a3)
> +	amocas.q.aqrl	a0, a5, (a3)
> diff --git a/gas/testsuite/gas/riscv/zacas-64.d b/gas/testsuite/gas/riscv/zacas-64.d
> new file mode 100644
> index 000000000000..027806aad4fc
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-64.d
> @@ -0,0 +1,21 @@
> +#as: -march=rv64i_zacas
> +#objdump: -d
> +
> +.*:[ 	]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <target>:
> +[ 	]+[0-9a-f]+:[ 	]+28f6a5af[ 	]+amocas\.w[ 		]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2cf6a5af[ 	]+amocas\.w\.aq[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2af6a5af[ 	]+amocas\.w\.rl[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ef6a5af[ 	]+amocas\.w\.aqrl[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+28f6b5af[ 	]+amocas\.d[ 		]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2cf6b5af[ 	]+amocas\.d\.aq[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2af6b5af[ 	]+amocas\.d\.rl[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ef6b5af[ 	]+amocas\.d\.aqrl[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+28e6c52f[ 	]+amocas\.q[ 		]+a0,a4,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ce6c52f[ 	]+amocas\.q\.aq[ 	]+a0,a4,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ae6c52f[ 	]+amocas\.q\.rl[ 	]+a0,a4,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ee6c52f[ 	]+amocas\.q\.aqrl[ 	]+a0,a4,\(a3\)
> diff --git a/gas/testsuite/gas/riscv/zacas-64.s b/gas/testsuite/gas/riscv/zacas-64.s
> new file mode 100644
> index 000000000000..3b9f7a0bfc7e
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-64.s
> @@ -0,0 +1,13 @@
> +target:
> +	amocas.w	a1, a5, (a3)
> +	amocas.w.aq	a1, a5, (a3)
> +	amocas.w.rl	a1, a5, (a3)
> +	amocas.w.aqrl	a1, a5, (a3)
> +	amocas.d	a1, a5, (a3)
> +	amocas.d.aq	a1, a5, (a3)
> +	amocas.d.rl	a1, a5, (a3)
> +	amocas.d.aqrl	a1, a5, (a3)
> +	amocas.q	a0, a4, (a3)
> +	amocas.q.aq	a0, a4, (a3)
> +	amocas.q.rl	a0, a4, (a3)
> +	amocas.q.aqrl	a0, a4, (a3)
> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
> index 375483500e2a..8fb59e3db93e 100644
> --- a/include/opcode/riscv-opc.h
> +++ b/include/opcode/riscv-opc.h
> @@ -2315,6 +2315,13 @@
>  #define MASK_C_NTL_S1 0xffff
>  #define MATCH_C_NTL_ALL 0x9016
>  #define MASK_C_NTL_ALL 0xffff
> +/* Zacas instructions.  */
> +#define MATCH_AMOCAS_D 0x2800302f
> +#define MASK_AMOCAS_D 0xf800707f
> +#define MATCH_AMOCAS_Q 0x2800402f
> +#define MASK_AMOCAS_Q 0xf800707f
> +#define MATCH_AMOCAS_W 0x2800202f
> +#define MASK_AMOCAS_W 0xf800707f
>  /* Zawrs instructions.  */
>  #define MATCH_WRS_NTO 0x00d00073
>  #define MASK_WRS_NTO 0xffffffff
> @@ -3370,6 +3377,10 @@ DECLARE_INSN(c_ntl_p1, MATCH_C_NTL_P1, MASK_C_NTL_P1)
>  DECLARE_INSN(c_ntl_pall, MATCH_C_NTL_PALL, MASK_C_NTL_PALL)
>  DECLARE_INSN(c_ntl_s1, MATCH_C_NTL_S1, MASK_C_NTL_S1)
>  DECLARE_INSN(c_ntl_all, MATCH_C_NTL_ALL, MASK_C_NTL_ALL)
> +/* Zacas instructions.  */
> +DECLARE_INSN(amocas_d, MATCH_AMOCAS_D, MASK_AMOCAS_D)
> +DECLARE_INSN(amocas_q, MATCH_AMOCAS_Q, MASK_AMOCAS_Q)
> +DECLARE_INSN(amocas_w, MATCH_AMOCAS_W, MASK_AMOCAS_W)
>  /* Zawrs instructions.  */
>  DECLARE_INSN(wrs_nto, MATCH_WRS_NTO, MASK_WRS_NTO)
>  DECLARE_INSN(wrs_sto, MATCH_WRS_STO, MASK_WRS_STO)
> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> index 93dd5169ebce..aefbfc7db81e 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -396,6 +396,7 @@ enum riscv_insn_class
>    INSN_CLASS_ZIHINTNTL_AND_C,
>    INSN_CLASS_ZIHINTPAUSE,
>    INSN_CLASS_ZMMUL,
> +  INSN_CLASS_ZACAS,
>    INSN_CLASS_ZAWRS,
>    INSN_CLASS_F_INX,
>    INSN_CLASS_D_INX,
> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> index 8e0ae85eb064..58087ca19cac 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -290,6 +290,24 @@ match_vd_eq_vs1_eq_vs2 (const struct riscv_opcode *op,
>    return match_opcode (op, insn) && vd == vs1 && vs1 == vs2;
>  }
>  
> +/* Instructions with register groups.  */
> +
> +#define DEFINE_MATCH_FUNC_R(G_RD,G_RS1,G_RS2) \
> +  static int \
> +  match_reggroup_r_##G_RD##_##G_RS1##_##G_RS2 (const struct riscv_opcode *op, \
> +					       insn_t insn) \
> +  { \
> +    int rd = (insn & MASK_RD) >> OP_SH_RD; \
> +    int rs1 = (insn & MASK_RS1) >> OP_SH_RS1; \
> +    int rs2 = (insn & MASK_RS2) >> OP_SH_RS2; \
> +    return match_opcode (op, insn) \
> +	   && (rd % G_RD == 0) \
> +	   && (rs1 % G_RS1 == 0) \
> +	   && (rs2 % G_RS2 == 0); \
> +  }
> +DEFINE_MATCH_FUNC_R(1, 1, 1)
> +DEFINE_MATCH_FUNC_R(2, 1, 2)
> +
>  static int
>  match_th_load_inc(const struct riscv_opcode *op,
>  		  insn_t insn)
> @@ -982,6 +1000,24 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"czero.eqz",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_EQZ, MASK_CZERO_EQZ, match_opcode, 0 },
>  {"czero.nez",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_NEZ, MASK_CZERO_NEZ, match_opcode, 0 },
>  
> +/* Zacas instructions.  */
> +{"amocas.w",       0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
> +{"amocas.w.aq",    0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W|MASK_AQ, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
> +{"amocas.w.rl",    0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W|MASK_RL, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
> +{"amocas.w.aqrl",  0, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_W|MASK_AQRL, MASK_AMOCAS_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
> +{"amocas.d",      32, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_8_BYTE },
> +{"amocas.d",      64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_1_1_1, INSN_DREF|INSN_8_BYTE },
> +{"amocas.d.aq",   32, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_AQ, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_8_BYTE },
> +{"amocas.d.aq",   64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_AQ, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_1_1_1, INSN_DREF|INSN_8_BYTE },
> +{"amocas.d.rl",   32, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_RL, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_8_BYTE },
> +{"amocas.d.rl",   64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_RL, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_1_1_1, INSN_DREF|INSN_8_BYTE },
> +{"amocas.d.aqrl", 32, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_AQRL, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_8_BYTE },
> +{"amocas.d.aqrl", 64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_D|MASK_AQRL, MASK_AMOCAS_D|MASK_AQRL, match_reggroup_r_1_1_1, INSN_DREF|INSN_8_BYTE },
> +{"amocas.q",      64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_Q, MASK_AMOCAS_Q|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_16_BYTE },
> +{"amocas.q.aq",   64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_Q|MASK_AQ, MASK_AMOCAS_Q|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_16_BYTE },
> +{"amocas.q.rl",   64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_Q|MASK_RL, MASK_AMOCAS_Q|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_16_BYTE },
> +{"amocas.q.aqrl", 64, INSN_CLASS_ZACAS, "d,t,0(s)", MATCH_AMOCAS_Q|MASK_AQRL, MASK_AMOCAS_Q|MASK_AQRL, match_reggroup_r_2_1_2, INSN_DREF|INSN_16_BYTE },
> +
>  /* Zawrs instructions.  */
>  {"wrs.nto",    0, INSN_CLASS_ZAWRS, "", MATCH_WRS_NTO, MASK_WRS_NTO, match_opcode, 0 },
>  {"wrs.sto",    0, INSN_CLASS_ZAWRS, "", MATCH_WRS_STO, MASK_WRS_STO, match_opcode, 0 },
> 
> base-commit: d249c8a63aec45648b2165532f79b09763870795

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

* Re: [PATCH v2] RISC-V: Add support for 'Zacas' atomic CAS
  2023-10-22  3:54 ` [PATCH v2] " Tsukasa OI
  2023-10-22  3:57   ` [REVIEW ONLY] UNRATIFIED RISC-V: Add support for 'Zabha' subword AMO extension Tsukasa OI
  2023-10-22  3:59   ` [PATCH v2] RISC-V: Add support for 'Zacas' atomic CAS Tsukasa OI
@ 2023-10-23  6:47   ` Jan Beulich
  2023-10-24  4:07     ` Tsukasa OI
  2 siblings, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2023-10-23  6:47 UTC (permalink / raw)
  To: Tsukasa OI
  Cc: binutils, Palmer Dabbelt, Andrew Waterman, Jim Wilson,
	Nelson Chu, Kito Cheng

On 22.10.2023 05:54, Tsukasa OI wrote:
> From: Tsukasa OI <research_trasio@irq.a4lg.com>
> 
> This commit adds support for the 'Zacas' extension, adding atomic CAS
> instructions.  Beware that this extension also introduces the concept of
> register pairs and it checks the validity of rs1 and rs2 if applicable.
> 
> This is based on the latest (frozen) draft:
> <https://github.com/riscv/riscv-zacas/releases/tag/v1.0-rc5>
> 
> bfd/ChangeLog:
> 
> 	* elfxx-riscv.c
> 	(riscv_implicit_subsets): Make 'Zacas' to imply 'A' extension.
> 	(riscv_supported_std_z_ext): Add 'Zacas' to the supported list.
> 	(riscv_multi_subset_supports, riscv_multi_subset_supports_ext):
> 	Add handling for new instruction class.
> 
> gas/ChangeLog:
> 
> 	* testsuite/gas/riscv/zacas-32.s: New test.
> 	* testsuite/gas/riscv/zacas-32.d: Likewise.
> 	* testsuite/gas/riscv/zacas-64.s: Likewise.
> 	* testsuite/gas/riscv/zacas-64.d: Likewise.
> 	* testsuite/gas/riscv/zacas-32-fail.s: New failure test.
> 	* testsuite/gas/riscv/zacas-32-fail.d: Likewise.
> 	* testsuite/gas/riscv/zacas-32-fail.l: Likewise.
> 	* testsuite/gas/riscv/zacas-64-fail.s: New failure test.
> 	* testsuite/gas/riscv/zacas-64-fail.d: Likewise.
> 	* testsuite/gas/riscv/zacas-64-fail.l: Likewise.
> 
> include/ChangeLog:
> 
> 	* opcode/riscv-opc.h (MATCH_AMOCAS_D, MASK_AMOCAS_D,
> 	MATCH_AMOCAS_Q, MASK_AMOCAS_Q, MATCH_AMOCAS_W,
> 	MASK_AMOCAS_W): New.
> 	* opcode/riscv.h (enum riscv_insn_class): Add new instruction
> 	class INSN_CLASS_ZACAS.
> 
> opcodes/ChangeLog:
> 
> 	* riscv-opc.c (REGGROUP_REGS_x, REGGROUP_REGS_1, REGGROUP_REGS_2,
> 	DEFINE_MATCH_FUNC_R): New match function template with register
> 	groups.
> 	(match_reggroup_r_1_1_1, match_reggroup_r_1_2_2): New.
> 	(riscv_opcodes): Add atomic CAS instructions.
> ---
>  bfd/elfxx-riscv.c                       |  6 +++++
>  gas/testsuite/gas/riscv/zacas-32-fail.d |  2 ++
>  gas/testsuite/gas/riscv/zacas-32-fail.l |  9 +++++++
>  gas/testsuite/gas/riscv/zacas-32-fail.s | 10 +++++++
>  gas/testsuite/gas/riscv/zacas-32.d      | 17 ++++++++++++
>  gas/testsuite/gas/riscv/zacas-32.s      |  9 +++++++
>  gas/testsuite/gas/riscv/zacas-64-fail.d |  2 ++
>  gas/testsuite/gas/riscv/zacas-64-fail.l |  9 +++++++
>  gas/testsuite/gas/riscv/zacas-64-fail.s | 10 +++++++
>  gas/testsuite/gas/riscv/zacas-64.d      | 21 +++++++++++++++
>  gas/testsuite/gas/riscv/zacas-64.s      | 13 +++++++++
>  include/opcode/riscv-opc.h              | 11 ++++++++
>  include/opcode/riscv.h                  |  1 +
>  opcodes/riscv-opc.c                     | 36 +++++++++++++++++++++++++
>  14 files changed, 156 insertions(+)
>  create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.d
>  create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.l
>  create mode 100644 gas/testsuite/gas/riscv/zacas-32-fail.s
>  create mode 100644 gas/testsuite/gas/riscv/zacas-32.d
>  create mode 100644 gas/testsuite/gas/riscv/zacas-32.s
>  create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.d
>  create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.l
>  create mode 100644 gas/testsuite/gas/riscv/zacas-64-fail.s
>  create mode 100644 gas/testsuite/gas/riscv/zacas-64.d
>  create mode 100644 gas/testsuite/gas/riscv/zacas-64.s
> 
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index c070394a3667..b7e067794ba8 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1148,6 +1148,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
>    {"zhinx", "zhinxmin",	check_implicit_always},
>    {"zhinxmin", "zfinx",	check_implicit_always},
>    {"zfinx", "zicsr",	check_implicit_always},
> +  {"zacas", "a",	check_implicit_always},
>    {"zk", "zkn",		check_implicit_always},
>    {"zk", "zkr",		check_implicit_always},
>    {"zk", "zkt",		check_implicit_always},
> @@ -1259,6 +1260,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
>    {"zihintntl",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
>    {"zihintpause",	ISA_SPEC_CLASS_DRAFT,		2, 0,  0 },
>    {"zmmul",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
> +  {"zacas",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
>    {"zawrs",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
>    {"zfa",		ISA_SPEC_CLASS_DRAFT,		0, 1,  0 },
>    {"zfh",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
> @@ -2409,6 +2411,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
>        return riscv_subset_supports (rps, "zmmul");
>      case INSN_CLASS_A:
>        return riscv_subset_supports (rps, "a");
> +    case INSN_CLASS_ZACAS:
> +      return riscv_subset_supports (rps, "zacas");
>      case INSN_CLASS_ZAWRS:
>        return riscv_subset_supports (rps, "zawrs");
>      case INSN_CLASS_F:
> @@ -2619,6 +2623,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
>        return _ ("m' or `zmmul");
>      case INSN_CLASS_A:
>        return "a";
> +    case INSN_CLASS_ZACAS:
> +      return "zacas";
>      case INSN_CLASS_ZAWRS:
>        return "zawrs";
>      case INSN_CLASS_F:
> diff --git a/gas/testsuite/gas/riscv/zacas-32-fail.d b/gas/testsuite/gas/riscv/zacas-32-fail.d
> new file mode 100644
> index 000000000000..12c1bd90ac86
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-32-fail.d
> @@ -0,0 +1,2 @@
> +#as: -march=rv32i_zacas
> +#error_output: zacas-32-fail.l
> diff --git a/gas/testsuite/gas/riscv/zacas-32-fail.l b/gas/testsuite/gas/riscv/zacas-32-fail.l
> new file mode 100644
> index 000000000000..944a66ba7806
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-32-fail.l
> @@ -0,0 +1,9 @@
> +.*: Assembler messages:
> +.*: Error: illegal operands `amocas\.d a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.d a0,a5,\(a3\)'
> +.*: Error: illegal operands `amocas\.d\.aq a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.d\.aq a0,a5,\(a3\)'
> +.*: Error: illegal operands `amocas\.d\.rl a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.d\.rl a0,a5,\(a3\)'
> +.*: Error: illegal operands `amocas\.d\.aqrl a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.d\.aqrl a0,a5,\(a3\)'
> diff --git a/gas/testsuite/gas/riscv/zacas-32-fail.s b/gas/testsuite/gas/riscv/zacas-32-fail.s
> new file mode 100644
> index 000000000000..650ea1d8b6f2
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-32-fail.s
> @@ -0,0 +1,10 @@
> +target:
> +	# amocas.d (RV32): rd (operand 1) and rs2 (operand 2) must be even.
> +	amocas.d	a1, a4, (a3)
> +	amocas.d	a0, a5, (a3)
> +	amocas.d.aq	a1, a4, (a3)
> +	amocas.d.aq	a0, a5, (a3)
> +	amocas.d.rl	a1, a4, (a3)
> +	amocas.d.rl	a0, a5, (a3)
> +	amocas.d.aqrl	a1, a4, (a3)
> +	amocas.d.aqrl	a0, a5, (a3)
> diff --git a/gas/testsuite/gas/riscv/zacas-32.d b/gas/testsuite/gas/riscv/zacas-32.d
> new file mode 100644
> index 000000000000..60f4fe09f866
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-32.d
> @@ -0,0 +1,17 @@
> +#as: -march=rv32i_zacas
> +#objdump: -d
> +
> +.*:[ 	]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <target>:
> +[ 	]+[0-9a-f]+:[ 	]+28f6a5af[ 	]+amocas\.w[ 		]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2cf6a5af[ 	]+amocas\.w\.aq[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2af6a5af[ 	]+amocas\.w\.rl[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ef6a5af[ 	]+amocas\.w\.aqrl[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+28e6b52f[ 	]+amocas\.d[ 		]+a0,a4,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ce6b52f[ 	]+amocas\.d\.aq[ 	]+a0,a4,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ae6b52f[ 	]+amocas\.d\.rl[ 	]+a0,a4,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ee6b52f[ 	]+amocas\.d\.aqrl[ 	]+a0,a4,\(a3\)
> diff --git a/gas/testsuite/gas/riscv/zacas-32.s b/gas/testsuite/gas/riscv/zacas-32.s
> new file mode 100644
> index 000000000000..c12c0e42f338
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-32.s
> @@ -0,0 +1,9 @@
> +target:
> +	amocas.w	a1, a5, (a3)
> +	amocas.w.aq	a1, a5, (a3)
> +	amocas.w.rl	a1, a5, (a3)
> +	amocas.w.aqrl	a1, a5, (a3)
> +	amocas.d	a0, a4, (a3)
> +	amocas.d.aq	a0, a4, (a3)
> +	amocas.d.rl	a0, a4, (a3)
> +	amocas.d.aqrl	a0, a4, (a3)
> diff --git a/gas/testsuite/gas/riscv/zacas-64-fail.d b/gas/testsuite/gas/riscv/zacas-64-fail.d
> new file mode 100644
> index 000000000000..e1910d81f9e2
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-64-fail.d
> @@ -0,0 +1,2 @@
> +#as: -march=rv64i_zacas
> +#error_output: zacas-64-fail.l
> diff --git a/gas/testsuite/gas/riscv/zacas-64-fail.l b/gas/testsuite/gas/riscv/zacas-64-fail.l
> new file mode 100644
> index 000000000000..74495401e153
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-64-fail.l
> @@ -0,0 +1,9 @@
> +.*: Assembler messages:
> +.*: Error: illegal operands `amocas\.q a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.q a0,a5,\(a3\)'
> +.*: Error: illegal operands `amocas\.q\.aq a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.q\.aq a0,a5,\(a3\)'
> +.*: Error: illegal operands `amocas\.q\.rl a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.q\.rl a0,a5,\(a3\)'
> +.*: Error: illegal operands `amocas\.q\.aqrl a1,a4,\(a3\)'
> +.*: Error: illegal operands `amocas\.q\.aqrl a0,a5,\(a3\)'
> diff --git a/gas/testsuite/gas/riscv/zacas-64-fail.s b/gas/testsuite/gas/riscv/zacas-64-fail.s
> new file mode 100644
> index 000000000000..96ee4a378bf5
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-64-fail.s
> @@ -0,0 +1,10 @@
> +target:
> +	# amocas.q (RV64): rd (operand 1) and rs2 (operand 2) must be even.
> +	amocas.q	a1, a4, (a3)
> +	amocas.q	a0, a5, (a3)
> +	amocas.q.aq	a1, a4, (a3)
> +	amocas.q.aq	a0, a5, (a3)
> +	amocas.q.rl	a1, a4, (a3)
> +	amocas.q.rl	a0, a5, (a3)
> +	amocas.q.aqrl	a1, a4, (a3)
> +	amocas.q.aqrl	a0, a5, (a3)
> diff --git a/gas/testsuite/gas/riscv/zacas-64.d b/gas/testsuite/gas/riscv/zacas-64.d
> new file mode 100644
> index 000000000000..027806aad4fc
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-64.d
> @@ -0,0 +1,21 @@
> +#as: -march=rv64i_zacas
> +#objdump: -d
> +
> +.*:[ 	]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <target>:
> +[ 	]+[0-9a-f]+:[ 	]+28f6a5af[ 	]+amocas\.w[ 		]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2cf6a5af[ 	]+amocas\.w\.aq[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2af6a5af[ 	]+amocas\.w\.rl[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ef6a5af[ 	]+amocas\.w\.aqrl[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+28f6b5af[ 	]+amocas\.d[ 		]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2cf6b5af[ 	]+amocas\.d\.aq[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2af6b5af[ 	]+amocas\.d\.rl[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ef6b5af[ 	]+amocas\.d\.aqrl[ 	]+a1,a5,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+28e6c52f[ 	]+amocas\.q[ 		]+a0,a4,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ce6c52f[ 	]+amocas\.q\.aq[ 	]+a0,a4,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ae6c52f[ 	]+amocas\.q\.rl[ 	]+a0,a4,\(a3\)
> +[ 	]+[0-9a-f]+:[ 	]+2ee6c52f[ 	]+amocas\.q\.aqrl[ 	]+a0,a4,\(a3\)
> diff --git a/gas/testsuite/gas/riscv/zacas-64.s b/gas/testsuite/gas/riscv/zacas-64.s
> new file mode 100644
> index 000000000000..3b9f7a0bfc7e
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zacas-64.s
> @@ -0,0 +1,13 @@
> +target:
> +	amocas.w	a1, a5, (a3)
> +	amocas.w.aq	a1, a5, (a3)
> +	amocas.w.rl	a1, a5, (a3)
> +	amocas.w.aqrl	a1, a5, (a3)
> +	amocas.d	a1, a5, (a3)
> +	amocas.d.aq	a1, a5, (a3)
> +	amocas.d.rl	a1, a5, (a3)
> +	amocas.d.aqrl	a1, a5, (a3)
> +	amocas.q	a0, a4, (a3)
> +	amocas.q.aq	a0, a4, (a3)
> +	amocas.q.rl	a0, a4, (a3)
> +	amocas.q.aqrl	a0, a4, (a3)
> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
> index 375483500e2a..8fb59e3db93e 100644
> --- a/include/opcode/riscv-opc.h
> +++ b/include/opcode/riscv-opc.h
> @@ -2315,6 +2315,13 @@
>  #define MASK_C_NTL_S1 0xffff
>  #define MATCH_C_NTL_ALL 0x9016
>  #define MASK_C_NTL_ALL 0xffff
> +/* Zacas instructions.  */
> +#define MATCH_AMOCAS_D 0x2800302f
> +#define MASK_AMOCAS_D 0xf800707f
> +#define MATCH_AMOCAS_Q 0x2800402f
> +#define MASK_AMOCAS_Q 0xf800707f
> +#define MATCH_AMOCAS_W 0x2800202f
> +#define MASK_AMOCAS_W 0xf800707f
>  /* Zawrs instructions.  */
>  #define MATCH_WRS_NTO 0x00d00073
>  #define MASK_WRS_NTO 0xffffffff
> @@ -3370,6 +3377,10 @@ DECLARE_INSN(c_ntl_p1, MATCH_C_NTL_P1, MASK_C_NTL_P1)
>  DECLARE_INSN(c_ntl_pall, MATCH_C_NTL_PALL, MASK_C_NTL_PALL)
>  DECLARE_INSN(c_ntl_s1, MATCH_C_NTL_S1, MASK_C_NTL_S1)
>  DECLARE_INSN(c_ntl_all, MATCH_C_NTL_ALL, MASK_C_NTL_ALL)
> +/* Zacas instructions.  */
> +DECLARE_INSN(amocas_d, MATCH_AMOCAS_D, MASK_AMOCAS_D)
> +DECLARE_INSN(amocas_q, MATCH_AMOCAS_Q, MASK_AMOCAS_Q)
> +DECLARE_INSN(amocas_w, MATCH_AMOCAS_W, MASK_AMOCAS_W)
>  /* Zawrs instructions.  */
>  DECLARE_INSN(wrs_nto, MATCH_WRS_NTO, MASK_WRS_NTO)
>  DECLARE_INSN(wrs_sto, MATCH_WRS_STO, MASK_WRS_STO)
> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> index 93dd5169ebce..aefbfc7db81e 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -396,6 +396,7 @@ enum riscv_insn_class
>    INSN_CLASS_ZIHINTNTL_AND_C,
>    INSN_CLASS_ZIHINTPAUSE,
>    INSN_CLASS_ZMMUL,
> +  INSN_CLASS_ZACAS,
>    INSN_CLASS_ZAWRS,
>    INSN_CLASS_F_INX,
>    INSN_CLASS_D_INX,
> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> index 8e0ae85eb064..58087ca19cac 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -290,6 +290,24 @@ match_vd_eq_vs1_eq_vs2 (const struct riscv_opcode *op,
>    return match_opcode (op, insn) && vd == vs1 && vs1 == vs2;
>  }
>  
> +/* Instructions with register groups.  */
> +
> +#define DEFINE_MATCH_FUNC_R(G_RD,G_RS1,G_RS2) \
> +  static int \
> +  match_reggroup_r_##G_RD##_##G_RS1##_##G_RS2 (const struct riscv_opcode *op, \
> +					       insn_t insn) \
> +  { \
> +    int rd = (insn & MASK_RD) >> OP_SH_RD; \
> +    int rs1 = (insn & MASK_RS1) >> OP_SH_RS1; \
> +    int rs2 = (insn & MASK_RS2) >> OP_SH_RS2; \
> +    return match_opcode (op, insn) \
> +	   && (rd % G_RD == 0) \
> +	   && (rs1 % G_RS1 == 0) \
> +	   && (rs2 % G_RS2 == 0); \
> +  }
> +DEFINE_MATCH_FUNC_R(1, 1, 1)
> +DEFINE_MATCH_FUNC_R(2, 1, 2)

Mind me asking what good the former of the two really does? It's just
match_opcode() aiui, properly obfuscated.

Jan

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

* Re: [PATCH v2] RISC-V: Add support for 'Zacas' atomic CAS
  2023-10-23  6:47   ` Jan Beulich
@ 2023-10-24  4:07     ` Tsukasa OI
  2023-10-24  6:02       ` Jan Beulich
  0 siblings, 1 reply; 11+ messages in thread
From: Tsukasa OI @ 2023-10-24  4:07 UTC (permalink / raw)
  To: Jan Beulich, Binutils

On 2023/10/23 15:47, Jan Beulich wrote:
> 
> Mind me asking what good the former of the two really does? It's just
> match_opcode() aiui, properly obfuscated.
> 
> Jan
> 

****Excuse me?****

As a single patch set, I think Gianluca's patch with a minor fix will
work perfectly.  But, the concept of register pairs / register groups
are not specific to 'Zacas', that's what I'm talking about and the
reason I think Gianluca's patch set's match function will not be a long
term solution (actually, I found Gianluca's patch set after I wrote
mine, but that wouldn't change my opinion).

So, let me list all register group-related constraints in existing and
upcoming extensions (except all ones; x is "not applicable" and can be
theoretically replaced to "1" but it's probably better to be named "x"
to indicate that the instruction does not use "x" operand as register):

Extension   |  RD | RS1 | RS2 | RS3
----------- | --- | --- | --- | ---
Zdinx       |   2 |   2 |   2 |   x
Zdinx       |   2 |   2 |   2 |   2
Zdinx       |   x |   2 |   2 |   x
Zdinx       |   1 |   2 |   x |   x
Zdinx       |   2 |   1 |   x |   x
Zdinx       |   2 |   2 |   x |   x
----------- | --- | --- | --- | ---
Zqinx       |   2 |   2 |   2 |   x
Zqinx       |   4 |   4 |   4 |   x
Zqinx       |   2 |   2 |   2 |   2
Zqinx       |   4 |   4 |   4 |   4
Zqinx       |   x |   2 |   2 |   x
Zqinx       |   x |   4 |   4 |   x
Zqinx       |   1 |   2 |   x |   x
Zqinx       |   1 |   4 |   x |   x
Zqinx       |   2 |   1 |   x |   x
Zqinx       |   2 |   2 |   x |   x
Zqinx       |   2 |   4 |   x |   x
Zqinx       |   4 |   1 |   x |   x
Zqinx       |   4 |   2 |   x |   x
Zqinx       |   4 |   4 |   x |   x
----------- | --- | --- | --- | ---
Zpsfoperand |   2 |   1 |   1 |   x
Zpsfoperand |   2 |   2 |   1 |   x
Zpsfoperand |   2 |   2 |   2 |   x
----------- | --- | --- | --- | ---
Zacas       |   2 |   1 |   2 |   x

Lots of similar constraints but different values.  Don't you think a
generator macro is the best solution for this kind of situation?

Tsukasa

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

* Re: [PATCH v2] RISC-V: Add support for 'Zacas' atomic CAS
  2023-10-24  4:07     ` Tsukasa OI
@ 2023-10-24  6:02       ` Jan Beulich
  2023-10-25  2:15         ` Nelson Chu
  0 siblings, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2023-10-24  6:02 UTC (permalink / raw)
  To: Tsukasa OI; +Cc: Binutils

On 24.10.2023 06:07, Tsukasa OI wrote:
> On 2023/10/23 15:47, Jan Beulich wrote:
>>
>> Mind me asking what good the former of the two really does? It's just
>> match_opcode() aiui, properly obfuscated.
>>
>> Jan
>>
> 
> ****Excuse me?****
> 
> As a single patch set, I think Gianluca's patch with a minor fix will
> work perfectly.  But, the concept of register pairs / register groups
> are not specific to 'Zacas', that's what I'm talking about and the
> reason I think Gianluca's patch set's match function will not be a long
> term solution (actually, I found Gianluca's patch set after I wrote
> mine, but that wouldn't change my opinion).
> 
> So, let me list all register group-related constraints in existing and
> upcoming extensions (except all ones; x is "not applicable" and can be
> theoretically replaced to "1" but it's probably better to be named "x"
> to indicate that the instruction does not use "x" operand as register):
> 
> Extension   |  RD | RS1 | RS2 | RS3
> ----------- | --- | --- | --- | ---
> Zdinx       |   2 |   2 |   2 |   x
> Zdinx       |   2 |   2 |   2 |   2
> Zdinx       |   x |   2 |   2 |   x
> Zdinx       |   1 |   2 |   x |   x
> Zdinx       |   2 |   1 |   x |   x
> Zdinx       |   2 |   2 |   x |   x
> ----------- | --- | --- | --- | ---
> Zqinx       |   2 |   2 |   2 |   x
> Zqinx       |   4 |   4 |   4 |   x
> Zqinx       |   2 |   2 |   2 |   2
> Zqinx       |   4 |   4 |   4 |   4
> Zqinx       |   x |   2 |   2 |   x
> Zqinx       |   x |   4 |   4 |   x
> Zqinx       |   1 |   2 |   x |   x
> Zqinx       |   1 |   4 |   x |   x
> Zqinx       |   2 |   1 |   x |   x
> Zqinx       |   2 |   2 |   x |   x
> Zqinx       |   2 |   4 |   x |   x
> Zqinx       |   4 |   1 |   x |   x
> Zqinx       |   4 |   2 |   x |   x
> Zqinx       |   4 |   4 |   x |   x
> ----------- | --- | --- | --- | ---
> Zpsfoperand |   2 |   1 |   1 |   x
> Zpsfoperand |   2 |   2 |   1 |   x
> Zpsfoperand |   2 |   2 |   2 |   x
> ----------- | --- | --- | --- | ---
> Zacas       |   2 |   1 |   2 |   x
> 
> Lots of similar constraints but different values.  Don't you think a
> generator macro is the best solution for this kind of situation?

Certainly, and I didn't put the macro under question. "The former of the
two" was referring to the invocation of the macro with all 1 arguments.
Interestingly this case also doesn't appear in the table above (for,
perhaps, the very reason I was asking the question).

Jan

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

* Re: [PATCH v2] RISC-V: Add support for 'Zacas' atomic CAS
  2023-10-24  6:02       ` Jan Beulich
@ 2023-10-25  2:15         ` Nelson Chu
  2023-10-25  6:02           ` Jan Beulich
  0 siblings, 1 reply; 11+ messages in thread
From: Nelson Chu @ 2023-10-25  2:15 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Tsukasa OI, Binutils

[-- Attachment #1: Type: text/plain, Size: 1723 bytes --]

On Tue, Oct 24, 2023 at 2:03 PM Jan Beulich <jbeulich@suse.com> wrote:

> On 24.10.2023 06:07, Tsukasa OI wrote:
> > As a single patch set, I think Gianluca's patch with a minor fix will
> > work perfectly.  But, the concept of register pairs / register groups
> > are not specific to 'Zacas', that's what I'm talking about and the
> > reason I think Gianluca's patch set's match function will not be a long
> > term solution (actually, I found Gianluca's patch set after I wrote
> > mine, but that wouldn't change my opinion).
>

As I said before, I don't know if we really need the constraint checks for
register groups in assembler or not.  Or on the other hand, I don't know if
we really need the detailed register constraint checks for assembly
syntax.  I remembered you completely unacceptable to fight back that you
don't care about hardware testing since you were doing toolchain, but for
those DV guys, they are also one of the users of toolchain.  However, for
many things, lots of users are used to using some behaviors or code in the
toolchain.  These behaviors are not wrong, maybe they are just not that
rigorous.  Even though your idea may be beneficial to some people, it can
also cause problems for others.

So, I was not rejecting your idea before, I was just trying to let you know
every change you made may cause trouble for others, especially that some
behaviors are established for many years.  Since the rvv register group
checks were argued before and removed, I will suggest we just
remove the same checks for zacas.  If other maintainers support that we
should also do these kinds of complicated constraint checks, then you can
ignore my comments.

Thanks
Nelson

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

* Re: [PATCH v2] RISC-V: Add support for 'Zacas' atomic CAS
  2023-10-25  2:15         ` Nelson Chu
@ 2023-10-25  6:02           ` Jan Beulich
  0 siblings, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2023-10-25  6:02 UTC (permalink / raw)
  To: Nelson Chu; +Cc: Tsukasa OI, Binutils

On 25.10.2023 04:15, Nelson Chu wrote:
> On Tue, Oct 24, 2023 at 2:03 PM Jan Beulich <jbeulich@suse.com> wrote:
> 
>> On 24.10.2023 06:07, Tsukasa OI wrote:
>>> As a single patch set, I think Gianluca's patch with a minor fix will
>>> work perfectly.  But, the concept of register pairs / register groups
>>> are not specific to 'Zacas', that's what I'm talking about and the
>>> reason I think Gianluca's patch set's match function will not be a long
>>> term solution (actually, I found Gianluca's patch set after I wrote
>>> mine, but that wouldn't change my opinion).
>>
> 
> As I said before, I don't know if we really need the constraint checks for
> register groups in assembler or not.  Or on the other hand, I don't know if
> we really need the detailed register constraint checks for assembly
> syntax.  I remembered you completely unacceptable to fight back that you
> don't care about hardware testing since you were doing toolchain, but for
> those DV guys, they are also one of the users of toolchain.  However, for
> many things, lots of users are used to using some behaviors or code in the
> toolchain.  These behaviors are not wrong, maybe they are just not that
> rigorous.  Even though your idea may be beneficial to some people, it can
> also cause problems for others.
> 
> So, I was not rejecting your idea before, I was just trying to let you know
> every change you made may cause trouble for others, especially that some
> behaviors are established for many years.  Since the rvv register group
> checks were argued before and removed, I will suggest we just
> remove the same checks for zacas.  If other maintainers support that we
> should also do these kinds of complicated constraint checks, then you can
> ignore my comments.

First, despite being sent To: me, I assume your reply was targeted at
Tsukasa?

Irrespective, while I'm not a RISC-V maintainer, I'd like to advocate in
favor of these checks (uniformly wherever applicable). If they pose
problems to certain people, let's have a command line option to suppress
them. (To some degree these checks are related to a remark towards hint
insns that I had raised quite some time ago: When doing things really
strictly, I continue to be of the opinion that those should only ever be
expressed as "hint", with their non-hint forms - e.g. some kind of ALU
insn with x0 as destination - at least warned about. The main issue
there obviously is how to pick among the many hint forms with just a
single "hint" mnemonic.)

Jan

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

* Re: [PATCH 0/1] RISC-V: Add support for 'Zacas' atomic CAS
  2023-10-21  3:12 [PATCH 0/1] RISC-V: Add support for 'Zacas' atomic CAS Tsukasa OI
  2023-10-21  3:12 ` [PATCH 1/1] " Tsukasa OI
  2023-10-22  3:54 ` [PATCH v2] " Tsukasa OI
@ 2023-12-06 18:39 ` Gianluca Guida
  2 siblings, 0 replies; 11+ messages in thread
From: Gianluca Guida @ 2023-12-06 18:39 UTC (permalink / raw)
  To: Tsukasa OI
  Cc: Palmer Dabbelt, Andrew Waterman, Jim Wilson, Nelson Chu,
	Kito Cheng, binutils

Hi Tsukasa,

I somehow missed this thread completely, as I wasn't in CC. Catching up now.

On Sat, Oct 21, 2023 at 4:12 AM Tsukasa OI <research_trasio@irq.a4lg.com> wrote:
>
> Differences to Gianluka's:
> 1.  Correct data size (INSN_DREF|INSN_*_BYTE) we are handling
Correct, that was in fact fixed in my patch on my current tree.
Surprised didn't catch that earlier.

> 2.  Make register pair matching function to be template
>     to enable reusing this framework for upcoming P and existing Zdinx and
>     V (many V cases are invalid only on certain runtime configuration and
>     "always invalid" detectable cases are rare, but not zero).

Sure, I wondered about other generalising support for pair of
registers, but I was expecting some kind of discussion on the review,
so I went for the simplest patch possible, when I implemented that in
the v2.

I don't have any strong opinion on which patch to use.

Gianluca.

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

end of thread, other threads:[~2023-12-06 18:39 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-21  3:12 [PATCH 0/1] RISC-V: Add support for 'Zacas' atomic CAS Tsukasa OI
2023-10-21  3:12 ` [PATCH 1/1] " Tsukasa OI
2023-10-22  3:54 ` [PATCH v2] " Tsukasa OI
2023-10-22  3:57   ` [REVIEW ONLY] UNRATIFIED RISC-V: Add support for 'Zabha' subword AMO extension Tsukasa OI
2023-10-22  3:59   ` [PATCH v2] RISC-V: Add support for 'Zacas' atomic CAS Tsukasa OI
2023-10-23  6:47   ` Jan Beulich
2023-10-24  4:07     ` Tsukasa OI
2023-10-24  6:02       ` Jan Beulich
2023-10-25  2:15         ` Nelson Chu
2023-10-25  6:02           ` Jan Beulich
2023-12-06 18:39 ` [PATCH 0/1] " Gianluca Guida

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).