@@ -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:
new file mode 100644
@@ -0,0 +1,2 @@
+#as: -march=rv32i_zacas
+#error_output: zacas-32-fail.l
new file mode 100644
@@ -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\)'
new file mode 100644
@@ -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)
new file mode 100644
@@ -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\)
new file mode 100644
@@ -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)
new file mode 100644
@@ -0,0 +1,2 @@
+#as: -march=rv64i_zacas
+#error_output: zacas-64-fail.l
new file mode 100644
@@ -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\)'
new file mode 100644
@@ -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)
new file mode 100644
@@ -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\)
new file mode 100644
@@ -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)
@@ -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)
@@ -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,
@@ -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 },