[1/1] RISC-V: Add support for 'Zacas' atomic CAS

Message ID 46829125b719deb9c4ea58cfacf1d36a7a31f0d3.1697857915.git.research_trasio@irq.a4lg.com
State New
Headers
Series RISC-V: Add support for 'Zacas' atomic CAS |

Checks

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

Commit Message

Tsukasa OI Oct. 21, 2023, 3:12 a.m. UTC
  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
  

Patch

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 },