[PATCH] RISC-V: Clarufy the behavior when extensions have superset.
Nelson Chu
nelson@rivosinc.com
Thu Nov 14 12:38:51 GMT 2024
If extensions have superset, then which means the superset includes those
extensions. We used to imply those extensions for the superset, and also
keep the superset since the canonical order form. For example,
* m includes zmmul, m implies zmmul
* b includes zba, zbb and zbs, and b also equals to zba + zbb + zbs, so b
implies zba, zbb and zbs
For all include rules,
m includes zmmul
zvbb includes zvkb
zhinx includes zhinxmin
zfh includes zfhmin
For all equal rules,
a equals to zaamo + zalrsc
b equals to zba + zbb + zbs
zks equals to zbkb + zbkc + zbkx + zksed + zksh
zkn equals to zbkb + zbkc + zbkx + zkne + zknd + zknh
zk equals to zkn + zkr + zkt
zvkn equals to zvkb + zvkt + zvkned + zvknhb
zvks equals to zvkb + zvkt + zvksed + zvksh
zvkng equals to zvkn + zvkg
zvknc equals to zvkn + zvbc
zvksg equals to zvks + zvkg
zvksc equals to zvks + zvbc
c equals to zca + zcf (if rv32 and f) + zcd (if d)
g is a super special case, so skip it here.
Considering ".option arch, -extension [,...,-extension_n]" removes the
extension which,
1. A includes B;
Remove A should also remove B;
Remove B is useless since we don't have any extensions to represent A - B
2. A equals to B + C + ...;
Remove A should also remove B, C and ...;
Remove B should also remove A, but keep C and ...;
Remove C should also remove A, but keep B and ...;
Remove B ansd C should also remove A, but keep ...;
3. A implies B;
Remove B is useless, since A still imply B;
Remove A doesn't affect B, since B may still be implied by others;
The rule 3 works for the current toolchain, so this patch mainly tries to fix
the rule 1 and 2, to keep the removing feature still work. The rules for c are
really complicated now because c represents different combinations in different
situations, so please see the all details in the option-arch-superset testsuite.
bfd/
* elfxx-riscv.c (check_implicit_always): Updated since check_func of
riscv_implicit_subset is changed.
(check_implicit_for_i): Likewise, also avoid segfault by NULL intputs.
(check_implicit_for_c_zcf): New function, only add c when rv32 and f.
(check_implicit_for_c_zcd): New function, only add c when d.
(struct riscv_implicit_subset): Updated check_func. Added new enum to
represent new imply types, which are normal imply, include, or equal.
(riscv_implicit_subsets): Added imply rule for c, and also updated all
imlpy types.
(riscv_parse_extract_subset): New function to extract extension and its
versions from the input string. This is the repeated code in the
riscv_parse_extensions, riscv_update_subset1 and riscv_update_superset.
(riscv_parse_extensions): Updated to call riscv_parse_extract_subset.
(riscv_update_subset1): Likewise. Remove all extensions if their
superset is removed. Also reports error when adding and removing
extensions at the same time.
(riscv_update_superset): New function. Remove the superset if its
sub-extension is removed.
(riscv_update_subset): Updated.
(riscv_multi_subset_supports): Don't check the superset if it has
equivalent extensions. Only INSN_CLASS of C need to be fixed.
(riscv_multi_subset_supports_ext): Just report the included and
equivalent extensions rather than the superset.
gas/
* config/tc-riscv.c (riscv_set_arch): Only need to check the zca for
riscv_set_rvc.
(s_riscv_option): Likewise.
* testsuite/gas/riscv/attribute-10.d: Updated since new imply rule of c.
* testsuite/gas/riscv/imply.d: Likewise.
* testsuite/gas/riscv/imply.s: Likewise.
* testsuite/gas/riscv/mapping-symbols.d: Likewise.
* testsuite/gas/riscv/march-ok-reorder.d: Likewise.
* testsuite/gas/riscv/option-arch-attr.d: Likewise.
* testsuite/gas/riscv/option-arch-dis.d: Likewise.
* testsuite/gas/riscv/option-arch-fail.l: Updated since the error
messag formats have been unified in riscv_parse_extract_subset. Also
report error when adding and removing extensions at the same time.
* testsuite/gas/riscv/option-arch-fail.s: Likewise.
* testsuite/gas/riscv/option-arch.s: Likewise.
* testsuite/gas/riscv/m-ext-fail-noarch-64.l: Updated since the change
in riscv_multi_subset_supports_ext.
* testsuite/gas/riscv/option-arch-superset.d: New testcase of superset.
* testsuite/gas/riscv/option-arch-superset.s: Likewise.
include/
* opcode/riscv.h: Changed INSN_CLASS_C, INSN_CLASS_F_AND_C,
INSN_CLASS_D_AND_C and INSN_CLASS_ZIHINTNTL_AND_C to INSN_CLASS_ZCA,
INSN_CLASS_ZCF, INSN_CLASS_ZCD and INSN_CLASS_ZIHINTNTL_AND_ZCA.
opcodes/
* riscv-opc.c: Updated since INSN_CLASS for C are changed.
---
bfd/elfxx-riscv.c | 629 +++++++++---------
gas/config/tc-riscv.c | 6 +-
gas/testsuite/gas/riscv/attribute-10.d | 2 +-
gas/testsuite/gas/riscv/imply.d | 5 +
gas/testsuite/gas/riscv/imply.s | 18 +-
.../gas/riscv/m-ext-fail-noarch-64.l | 10 +-
gas/testsuite/gas/riscv/mapping-symbols.d | 22 +-
gas/testsuite/gas/riscv/march-ok-reorder.d | 2 +-
gas/testsuite/gas/riscv/option-arch-attr.d | 2 +-
gas/testsuite/gas/riscv/option-arch-dis.d | 6 +-
gas/testsuite/gas/riscv/option-arch-fail.l | 15 +-
gas/testsuite/gas/riscv/option-arch-fail.s | 3 +-
.../gas/riscv/option-arch-superset.d | 154 +++++
.../gas/riscv/option-arch-superset.s | 180 +++++
gas/testsuite/gas/riscv/option-arch.s | 3 +-
include/opcode/riscv.h | 8 +-
opcodes/riscv-opc.c | 294 ++++----
17 files changed, 869 insertions(+), 490 deletions(-)
create mode 100644 gas/testsuite/gas/riscv/option-arch-superset.d
create mode 100644 gas/testsuite/gas/riscv/option-arch-superset.s
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 4b48d8ee9f0..5ee9fe73940 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1148,7 +1148,8 @@ riscv_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
/* Always add implicit extensions for the SUBSET. */
static bool
-check_implicit_always (riscv_subset_t *subset ATTRIBUTE_UNUSED)
+check_implicit_always (riscv_parse_subset_t *rps ATTRIBUTE_UNUSED,
+ riscv_subset_t *subset ATTRIBUTE_UNUSED)
{
return true;
}
@@ -1156,11 +1157,35 @@ check_implicit_always (riscv_subset_t *subset ATTRIBUTE_UNUSED)
/* Add implicit extensions only when the version of SUBSET less than 2.1. */
static bool
-check_implicit_for_i (riscv_subset_t *subset)
+check_implicit_for_i (riscv_parse_subset_t *rps ATTRIBUTE_UNUSED,
+ riscv_subset_t *subset)
{
- return (subset->major_version < 2
- || (subset->major_version == 2
- && subset->minor_version < 1));
+ return (subset != NULL
+ && (subset->major_version < 2
+ || (subset->major_version == 2
+ && subset->minor_version < 1)));
+}
+
+/* Add implicit extension only when rv32 and f existing. */
+
+static bool
+check_implicit_for_c_zcf (riscv_parse_subset_t *rps,
+ riscv_subset_t *subset ATTRIBUTE_UNUSED)
+{
+ return (rps != NULL
+ && rps->xlen != NULL
+ && *rps->xlen == 32
+ && riscv_subset_supports (rps, "f"));
+}
+
+/* Add implicit extension only when d existing. */
+
+static bool
+check_implicit_for_c_zcd (riscv_parse_subset_t *rps,
+ riscv_subset_t *subset ATTRIBUTE_UNUSED)
+{
+ return (rps != NULL
+ && riscv_subset_supports (rps, "d"));
}
/* Record all implicit information for the subsets. */
@@ -1169,108 +1194,114 @@ struct riscv_implicit_subset
const char *ext;
const char *implicit_exts;
/* A function to determine if we need to add the implicit subsets. */
- bool (*check_func) (riscv_subset_t *);
+ bool (*check_func) (riscv_parse_subset_t *rps, riscv_subset_t *);
+ enum implicit_type {IMPLY, INCLUDE, EQUAL} type;
};
/* Please added in order since this table is only run once time. */
static struct riscv_implicit_subset riscv_implicit_subsets[] =
{
- {"g", "+i,+m,+a,+f,+d,+zicsr,+zifencei", check_implicit_always},
- {"e", "+i", check_implicit_always},
- {"i", "+zicsr,+zifencei", check_implicit_for_i},
- {"zicntr", "+zicsr", check_implicit_always},
- {"zihpm", "+zicsr", check_implicit_always},
-
- {"m", "+zmmul", check_implicit_always},
-
- {"zabha", "+zaamo", check_implicit_always},
- {"zacas", "+zaamo", check_implicit_always},
- {"a", "+zaamo,+zalrsc", check_implicit_always},
-
- {"xsfvcp", "+zve32x", check_implicit_always},
- {"v", "+zve64d,+zvl128b", check_implicit_always},
- {"zvfh", "+zvfhmin,+zfhmin", check_implicit_always},
- {"zvfhmin", "+zve32f", check_implicit_always},
- {"zvfbfwma", "+zve32f,+zfbfmin", check_implicit_always},
- {"zvfbfmin", "+zve32f", check_implicit_always},
- {"zve64d", "+d,+zve64f", check_implicit_always},
- {"zve64f", "+zve32f,+zve64x,+zvl64b", check_implicit_always},
- {"zve32f", "+f,+zve32x,+zvl32b", check_implicit_always},
- {"zve64x", "+zve32x,+zvl64b", check_implicit_always},
- {"zve32x", "+zvl32b,+zicsr", check_implicit_always},
- {"zvl65536b", "+zvl32768b", check_implicit_always},
- {"zvl32768b", "+zvl16384b", check_implicit_always},
- {"zvl16384b", "+zvl8192b", check_implicit_always},
- {"zvl8192b", "+zvl4096b", check_implicit_always},
- {"zvl4096b", "+zvl2048b", check_implicit_always},
- {"zvl2048b", "+zvl1024b", check_implicit_always},
- {"zvl1024b", "+zvl512b", check_implicit_always},
- {"zvl512b", "+zvl256b", check_implicit_always},
- {"zvl256b", "+zvl128b", check_implicit_always},
- {"zvl128b", "+zvl64b", check_implicit_always},
- {"zvl64b", "+zvl32b", check_implicit_always},
-
- {"zcb", "+zca", check_implicit_always},
- {"zcd", "+d,+zca", check_implicit_always},
- {"zcf", "+f,+zca", check_implicit_always},
- {"zcmp", "+zca", check_implicit_always},
- {"zcmop", "+zca", check_implicit_always},
-
- {"shcounterenw", "+h", check_implicit_always},
- {"shgatpa", "+h", check_implicit_always},
- {"shtvala", "+h", check_implicit_always},
- {"shvsatpa", "+h", check_implicit_always},
- {"shvstvala", "+h", check_implicit_always},
- {"shvstvecd", "+h", check_implicit_always},
- {"h", "+zicsr", check_implicit_always},
- {"zhinx", "+zhinxmin", check_implicit_always},
- {"zhinxmin", "+zfinx", check_implicit_always},
-
- {"q", "+d", check_implicit_always},
- {"zqinx", "+zdinx", check_implicit_always},
-
- {"d", "+f", check_implicit_always},
- {"zdinx", "+zfinx", check_implicit_always},
-
- {"zfa", "+f", check_implicit_always},
- {"zfbfmin", "+zfhmin", check_implicit_always},
- {"zfh", "+zfhmin", check_implicit_always},
- {"zfhmin", "+f", check_implicit_always},
- {"zfinx", "+zicsr", check_implicit_always},
- {"f", "+zicsr", check_implicit_always},
-
- {"b", "+zba,+zbb,+zbs", check_implicit_always},
-
- {"zk", "+zkn,+zkr,+zkt", check_implicit_always},
- {"zkn", "+zbkb,+zbkc,+zbkx,+zkne,+zknd,+zknh", check_implicit_always},
- {"zks", "+zbkb,+zbkc,+zbkx,+zksed,+zksh", check_implicit_always},
- {"zvbb", "+zvkb", check_implicit_always},
- {"zvkng", "+zvkn,+zvkg", check_implicit_always},
- {"zvknc", "+zvkn,+zvbc", check_implicit_always},
- {"zvkn", "+zvkned,+zvknhb,+zvkb,+zvkt", check_implicit_always},
- {"zvksg", "+zvks,+zvkg", check_implicit_always},
- {"zvksc", "+zvks,+zvbc", check_implicit_always},
- {"zvks", "+zvksed,+zvksh,+zvkb,+zvkt", check_implicit_always},
-
- {"smaia", "+ssaia", check_implicit_always},
- {"smcsrind", "+sscsrind", check_implicit_always},
- {"smcntrpmf", "+zicsr", check_implicit_always},
- {"smstateen", "+ssstateen", check_implicit_always},
- {"smepmp", "+zicsr", check_implicit_always},
-
- {"ssaia", "+zicsr", check_implicit_always},
- {"sscsrind", "+zicsr", check_implicit_always},
- {"sscofpmf", "+zicsr", check_implicit_always},
- {"sscounterenw", "+zicsr", check_implicit_always},
- {"ssstateen", "+zicsr", check_implicit_always},
- {"sstc", "+zicsr", check_implicit_always},
- {"sstvala", "+zicsr", check_implicit_always},
- {"sstvecd", "+zicsr", check_implicit_always},
- {"ssu64xl", "+zicsr", check_implicit_always},
-
- {"svade", "+zicsr", check_implicit_always},
- {"svadu", "+zicsr", check_implicit_always},
- {"svbare", "+zicsr", check_implicit_always},
- {NULL, NULL, NULL}
+ {"g", "+i,+m,+a,+f,+d,+zicsr,+zifencei", check_implicit_always, IMPLY},
+ {"e", "+i", check_implicit_always, IMPLY},
+ {"i", "+zicsr,+zifencei", check_implicit_for_i, IMPLY},
+ {"zicntr", "+zicsr", check_implicit_always, IMPLY},
+ {"zihpm", "+zicsr", check_implicit_always, IMPLY},
+
+ {"m", "+zmmul", check_implicit_always, INCLUDE},
+
+ {"zabha", "+zaamo", check_implicit_always, IMPLY},
+ {"zacas", "+zaamo", check_implicit_always, IMPLY},
+ {"a", "+zaamo,+zalrsc", check_implicit_always, EQUAL},
+
+ {"xsfvcp", "+zve32x", check_implicit_always, IMPLY},
+ {"v", "+zve64d,+zvl128b", check_implicit_always, IMPLY},
+ {"zvfh", "+zvfhmin,+zfhmin", check_implicit_always, IMPLY},
+ {"zvfhmin", "+zve32f", check_implicit_always, IMPLY},
+ {"zvfbfwma", "+zve32f,+zfbfmin", check_implicit_always, IMPLY},
+ {"zvfbfmin", "+zve32f", check_implicit_always, IMPLY},
+ {"zve64d", "+d,+zve64f", check_implicit_always, IMPLY},
+ {"zve64f", "+zve32f,+zve64x,+zvl64b", check_implicit_always, IMPLY},
+ {"zve32f", "+f,+zve32x,+zvl32b", check_implicit_always, IMPLY},
+ {"zve64x", "+zve32x,+zvl64b", check_implicit_always, IMPLY},
+ {"zve32x", "+zvl32b,+zicsr", check_implicit_always, IMPLY},
+ {"zvl65536b", "+zvl32768b", check_implicit_always, IMPLY},
+ {"zvl32768b", "+zvl16384b", check_implicit_always, IMPLY},
+ {"zvl16384b", "+zvl8192b", check_implicit_always, IMPLY},
+ {"zvl8192b", "+zvl4096b", check_implicit_always, IMPLY},
+ {"zvl4096b", "+zvl2048b", check_implicit_always, IMPLY},
+ {"zvl2048b", "+zvl1024b", check_implicit_always, IMPLY},
+ {"zvl1024b", "+zvl512b", check_implicit_always, IMPLY},
+ {"zvl512b", "+zvl256b", check_implicit_always, IMPLY},
+ {"zvl256b", "+zvl128b", check_implicit_always, IMPLY},
+ {"zvl128b", "+zvl64b", check_implicit_always, IMPLY},
+ {"zvl64b", "+zvl32b", check_implicit_always, IMPLY},
+
+ {"zcb", "+zca", check_implicit_always, IMPLY},
+ {"zcd", "+d,+zca", check_implicit_always, IMPLY},
+ {"zcf", "+f,+zca", check_implicit_always, IMPLY},
+ {"zcmp", "+zca", check_implicit_always, IMPLY},
+ {"zcmop", "+zca", check_implicit_always, IMPLY},
+
+ {"shcounterenw", "+h", check_implicit_always, IMPLY},
+ {"shgatpa", "+h", check_implicit_always, IMPLY},
+ {"shtvala", "+h", check_implicit_always, IMPLY},
+ {"shvsatpa", "+h", check_implicit_always, IMPLY},
+ {"shvstvala", "+h", check_implicit_always, IMPLY},
+ {"shvstvecd", "+h", check_implicit_always, IMPLY},
+ {"h", "+zicsr", check_implicit_always, IMPLY},
+ {"zhinx", "+zhinxmin", check_implicit_always, INCLUDE},
+ {"zhinxmin", "+zfinx", check_implicit_always, IMPLY},
+
+ {"q", "+d", check_implicit_always, IMPLY},
+ {"zqinx", "+zdinx", check_implicit_always, IMPLY},
+
+ {"d", "+f", check_implicit_always, IMPLY},
+ {"zdinx", "+zfinx", check_implicit_always, IMPLY},
+
+ {"zfa", "+f", check_implicit_always, IMPLY},
+ {"zfbfmin", "+zfhmin", check_implicit_always, IMPLY},
+ {"zfh", "+zfhmin", check_implicit_always, INCLUDE},
+ {"zfhmin", "+f", check_implicit_always, IMPLY},
+ {"zfinx", "+zicsr", check_implicit_always, IMPLY},
+ {"f", "+zicsr", check_implicit_always, IMPLY},
+
+ /* c = zca + zcf (if f) + zcd (if d). */
+ {"c", "+zcf", check_implicit_for_c_zcf, EQUAL},
+ {"c", "+zcd", check_implicit_for_c_zcd, EQUAL},
+ {"c", "+zca", check_implicit_always, EQUAL},
+
+ {"b", "+zba,+zbb,+zbs", check_implicit_always, EQUAL},
+
+ {"zk", "+zkn,+zkr,+zkt", check_implicit_always, EQUAL},
+ {"zkn", "+zbkb,+zbkc,+zbkx,+zkne,+zknd,+zknh", check_implicit_always, EQUAL},
+ {"zks", "+zbkb,+zbkc,+zbkx,+zksed,+zksh", check_implicit_always, EQUAL},
+ {"zvbb", "+zvkb", check_implicit_always, INCLUDE},
+ {"zvkng", "+zvkn,+zvkg", check_implicit_always, EQUAL},
+ {"zvknc", "+zvkn,+zvbc", check_implicit_always, EQUAL},
+ {"zvkn", "+zvkned,+zvknhb,+zvkb,+zvkt", check_implicit_always, EQUAL},
+ {"zvksg", "+zvks,+zvkg", check_implicit_always, EQUAL},
+ {"zvksc", "+zvks,+zvbc", check_implicit_always, EQUAL},
+ {"zvks", "+zvksed,+zvksh,+zvkb,+zvkt", check_implicit_always, EQUAL},
+
+ {"smaia", "+ssaia", check_implicit_always, IMPLY},
+ {"smcsrind", "+sscsrind", check_implicit_always, IMPLY},
+ {"smcntrpmf", "+zicsr", check_implicit_always, IMPLY},
+ {"smstateen", "+ssstateen", check_implicit_always, IMPLY},
+ {"smepmp", "+zicsr", check_implicit_always, IMPLY},
+
+ {"ssaia", "+zicsr", check_implicit_always, IMPLY},
+ {"sscsrind", "+zicsr", check_implicit_always, IMPLY},
+ {"sscofpmf", "+zicsr", check_implicit_always, IMPLY},
+ {"sscounterenw", "+zicsr", check_implicit_always, IMPLY},
+ {"ssstateen", "+zicsr", check_implicit_always, IMPLY},
+ {"sstc", "+zicsr", check_implicit_always, IMPLY},
+ {"sstvala", "+zicsr", check_implicit_always, IMPLY},
+ {"sstvecd", "+zicsr", check_implicit_always, IMPLY},
+ {"ssu64xl", "+zicsr", check_implicit_always, IMPLY},
+
+ {"svade", "+zicsr", check_implicit_always, IMPLY},
+ {"svadu", "+zicsr", check_implicit_always, IMPLY},
+ {"svbare", "+zicsr", check_implicit_always, IMPLY},
+ {NULL, NULL, NULL, 0}
};
/* For default_enable field, decide if the extension should
@@ -1895,6 +1926,79 @@ riscv_parsing_subset_version (const char *p,
return p;
}
+/* Extract extension and it's versions from the string ARCH. */
+
+static bool
+riscv_parse_extract_subset (riscv_parse_subset_t *rps, const char *arch, char s,
+ char *subset, const char **end_of_version,
+ int *major_version, int *minor_version)
+{
+ char *q = subset;
+ /* Extract the whole prefixed extension by S. */
+ while (*q != '\0' && *q != s)
+ q++;
+
+ /* Look forward to the first letter which is not <major>p<minor>. */
+ bool find_any_version = false;
+ bool find_minor_version = false;
+ size_t len = q - subset;
+ size_t i;
+ for (i = len; i > 0; i--)
+ {
+ q--;
+ if (ISDIGIT (*q))
+ find_any_version = true;
+ else if (find_any_version
+ && !find_minor_version
+ && *q == 'p'
+ && ISDIGIT (*(q - 1)))
+ find_minor_version = true;
+ else
+ break;
+ }
+ if (len > 0)
+ q++;
+
+ /* Check if the end of extension is 'p' or not. If yes, then
+ the second letter from the end cannot be number. */
+ if (len > 1 && *(q - 1) == 'p' && ISDIGIT (*(q - 2)))
+ {
+ *q = '\0';
+ rps->error_handler
+ (_("%s: invalid prefixed ISA extension `%s' ends with <number>p"),
+ arch, subset);
+ return false;
+ }
+
+ *end_of_version =
+ riscv_parsing_subset_version (q, major_version, minor_version);
+ *q = '\0';
+ if (*end_of_version == NULL)
+ return false;
+
+ const char *msg = NULL;
+ bool standard = strlen (subset) == 1
+ && riscv_get_prefix_class (subset) == RV_ISA_CLASS_SINGLE;
+ if (strlen (subset) == 0)
+ msg = "";
+ else if (standard
+ && riscv_ext_order[(*subset - 'a')] == 0)
+ msg = _("standard ");
+ else if (!standard
+ && rps->check_unknown_prefixed_ext
+ && !riscv_recognized_prefixed_ext (subset))
+ msg = _("prefixed ");
+ if (msg != NULL)
+ {
+ rps->error_handler
+ (_("%s: unknown %sISA extension `%s'"),
+ arch, msg, subset);
+ return false;
+ }
+
+ return true;
+}
+
/* Parsing function for both standard and prefixed extensions.
Return Value:
@@ -1930,6 +2034,8 @@ riscv_parse_extensions (riscv_parse_subset_t *rps,
char *subset = xstrdup (p);
char *q = subset; /* Start of version. */
const char *end_of_version;
+ int major_version = RISCV_UNKNOWN_VERSION;
+ int minor_version = RISCV_UNKNOWN_VERSION;
bool implicit = false;
enum riscv_prefix_ext_class class = riscv_get_prefix_class (p);
@@ -1944,62 +2050,19 @@ riscv_parse_extensions (riscv_parse_subset_t *rps,
return NULL;
}
q++;
- }
- else
- {
- /* Extract the whole prefixed extension by '_'. */
- while (*++q != '\0' && *q != '_')
- ;
- /* Look forward to the first letter which is not <major>p<minor>. */
- bool find_any_version = false;
- bool find_minor_version = false;
- while (1)
- {
- q--;
- if (ISDIGIT (*q))
- find_any_version = true;
- else if (find_any_version
- && !find_minor_version
- && *q == 'p'
- && ISDIGIT (*(q - 1)))
- find_minor_version = true;
- else
- break;
- }
- q++;
-
- /* Check if the end of extension is 'p' or not. If yes, then
- the second letter from the end cannot be number. */
- if (*(q - 1) == 'p' && ISDIGIT (*(q - 2)))
+ end_of_version =
+ riscv_parsing_subset_version (q, &major_version, &minor_version);
+ *q = '\0';
+ if (end_of_version == NULL)
{
- *q = '\0';
- rps->error_handler
- (_("%s: invalid prefixed ISA extension `%s' ends with <number>p"),
- arch, subset);
free (subset);
return NULL;
}
}
-
- int major_version = RISCV_UNKNOWN_VERSION;
- int minor_version = RISCV_UNKNOWN_VERSION;
- end_of_version =
- riscv_parsing_subset_version (q, &major_version, &minor_version);
- *q = '\0';
- if (end_of_version == NULL)
- {
- free (subset);
- return NULL;
- }
-
- /* Check if the prefixed extension name is well-formed. */
- if (class != RV_ISA_CLASS_SINGLE
- && rps->check_unknown_prefixed_ext
- && !riscv_recognized_prefixed_ext (subset))
+ else if (!riscv_parse_extract_subset (rps, arch, '_', subset,
+ &end_of_version, &major_version,
+ &minor_version))
{
- rps->error_handler
- (_("%s: unknown prefixed ISA extension `%s'"),
- arch, subset);
free (subset);
return NULL;
}
@@ -2032,7 +2095,7 @@ riscv_parse_extensions (riscv_parse_subset_t *rps,
}
static bool
-riscv_update_subset1 (riscv_parse_subset_t *, riscv_subset_t *, const char *);
+riscv_update_subset1 (riscv_parse_subset_t *, const char *);
/* Add the implicit extensions. */
@@ -2044,8 +2107,8 @@ riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
{
riscv_subset_t *subset = NULL;
if (riscv_lookup_subset (rps->subset_list, t->ext, &subset)
- && t->check_func (subset))
- riscv_update_subset1 (rps, subset, t->implicit_exts);
+ && t->check_func (rps, subset))
+ riscv_update_subset1 (rps, t->implicit_exts);
}
}
@@ -2376,119 +2439,123 @@ riscv_remove_subset (riscv_subset_list_t *subset_list,
}
}
-/* Auxiliary to add/remove extensions to/from the subset list.
- This is called from riscv_update_subset or riscv_parse_add_implicit_subsets.
+/* If the removed subsets are belonged to supersets, then also remove them. */
+
+static void
+riscv_update_superset (riscv_parse_subset_t *rps)
+{
+ struct riscv_implicit_subset *t = riscv_implicit_subsets;
+ int n = sizeof (riscv_implicit_subsets) / sizeof (*t);
+ for (n = n - 2; n > 0; n--)
+ {
+ if (t[n].type != EQUAL
+ || !t[n].check_func (rps, NULL))
+ continue;
- The EXPLICIT_SUBSET, the corresponding explicit extension. It is NULL means
- called from riscv_update_subset./
+ const char *p = t[n].implicit_exts;
+ bool superset = true;
+ do
+ {
+ /* Skip `+' and `-'. */
+ p++;
+ char *ext = xstrdup (p);
+ const char *end_of_version;
+ int major_version = RISCV_UNKNOWN_VERSION;
+ int minor_version = RISCV_UNKNOWN_VERSION;
+ riscv_parse_extract_subset (rps, t[n].implicit_exts, ',', ext,
+ &end_of_version, &major_version,
+ &minor_version);
+ riscv_subset_t *subset = NULL;
+ if (!riscv_lookup_subset (rps->subset_list, ext, &subset))
+ {
+ superset = false;
+ free (ext);
+ break;
+ }
+ p += end_of_version - ext;
+ free (ext);
+ }
+ while (*p++ == ',');
+
+ if (!superset)
+ riscv_remove_subset (rps->subset_list, t[n].ext);
+ }
+}
- The IMPLICIT_EXTS, +extension[version] [,...,+extension_n[version_n]]
- -extension [,...,-extension_n],
- full ISA. */
+/* Auxiliary to add/remove extensions to/from the subset list.
+
+ The EXTS, +extension[version] [,...,+extension_n[version_n]]
+ -extension [,...,-extension_n],
+ full ISA. */
static bool
riscv_update_subset1 (riscv_parse_subset_t *rps,
- riscv_subset_t *explicit_subset,
- const char *implicit_exts)
+ const char *exts)
{
- const char *p = implicit_exts;
- const char *errmsg_internal = explicit_subset == NULL ? "" : _("internal: ");
- const char *errmsg_caller = explicit_subset == NULL
- ? ".option arch" : "riscv_implicit_subsets";
+ const char *p = exts;
+ enum btype {UNCLEAR, ADD, SUB};
+ enum btype behavior = UNCLEAR;
do
{
- int major_version = RISCV_UNKNOWN_VERSION;
- int minor_version = RISCV_UNKNOWN_VERSION;
-
- bool removed = false;
switch (*p)
{
- case '+': removed = false; break;
- case '-': removed = true; break;
+ case '+': behavior = (behavior == SUB) ? UNCLEAR : ADD; break;
+ case '-': behavior = (behavior == ADD) ? UNCLEAR : SUB; break;
default:
riscv_release_subset_list (rps->subset_list);
return riscv_parse_subset (rps, p);
}
++p;
- char *subset = xstrdup (p);
- char *q = subset;
- const char *end_of_version;
- /* Extract the whole prefixed extension by ','. */
- while (*q != '\0' && *q != ',')
- q++;
-
- /* Look forward to the first letter which is not <major>p<minor>. */
- bool find_any_version = false;
- bool find_minor_version = false;
- size_t len = q - subset;
- size_t i;
- for (i = len; i > 0; i--)
- {
- q--;
- if (ISDIGIT (*q))
- find_any_version = true;
- else if (find_any_version
- && !find_minor_version
- && *q == 'p'
- && ISDIGIT (*(q - 1)))
- find_minor_version = true;
- else
- break;
- }
- if (len > 0)
- q++;
-
- /* Check if the end of extension is 'p' or not. If yes, then
- the second letter from the end cannot be number. */
- if (len > 1 && *(q - 1) == 'p' && ISDIGIT (*(q - 2)))
+ if (behavior == UNCLEAR)
{
- *q = '\0';
rps->error_handler
- (_("%sinvalid ISA extension ends with <number>p in %s `%s'"),
- errmsg_internal, errmsg_caller, implicit_exts);
- free (subset);
+ (_("%s: cannot mix `+' and `-' at the same time"), exts);
return false;
}
- end_of_version =
- riscv_parsing_subset_version (q, &major_version, &minor_version);
- *q = '\0';
- if (end_of_version == NULL)
+ char *subset = xstrdup (p);
+ const char *end_of_version;
+ int major_version = RISCV_UNKNOWN_VERSION;
+ int minor_version = RISCV_UNKNOWN_VERSION;
+ if (!riscv_parse_extract_subset (rps, exts, ',', subset, &end_of_version,
+ &major_version, &minor_version))
{
free (subset);
return false;
}
- if (strlen (subset) == 0
- || (strlen (subset) == 1
- && riscv_ext_order[(*subset - 'a')] == 0)
- || (strlen (subset) > 1
- && rps->check_unknown_prefixed_ext
- && !riscv_recognized_prefixed_ext (subset)))
+ if (behavior == SUB)
{
- rps->error_handler
- (_("%sunknown ISA extension `%s' in %s `%s'"),
- errmsg_internal, subset, errmsg_caller, implicit_exts);
- free (subset);
- return false;
- }
-
- if (explicit_subset == NULL
- && (strcmp (subset, "i") == 0
+ if (strcmp (subset, "i") == 0
|| strcmp (subset, "e") == 0
- || strcmp (subset, "g") == 0))
- {
- rps->error_handler
- (_("%scannot + or - base extension `%s' in %s `%s'"),
- errmsg_internal, subset, errmsg_caller, implicit_exts);
- free (subset);
- return false;
- }
+ || strcmp (subset, "g") == 0)
+ {
+ rps->error_handler
+ (_("%s: cannot remove base extension `%s'"), exts, subset);
+ free (subset);
+ return false;
+ }
- if (removed)
- riscv_remove_subset (rps->subset_list, subset);
+ struct riscv_implicit_subset *t = riscv_implicit_subsets;
+ for (; t->ext; t++)
+ {
+ if ((t->type == INCLUDE || t->type == EQUAL)
+ && strcmp (subset, t->ext) == 0
+ && t->check_func (rps, NULL))
+ {
+ char *include_exts = xstrdup (t->implicit_exts);
+ char *pp = include_exts;
+ for (; *pp != '\0'; pp++)
+ if (*pp == '+')
+ *pp = '-';
+ riscv_update_subset1 (rps, include_exts);
+ free (include_exts);
+ }
+ }
+ riscv_remove_subset (rps->subset_list, subset);
+ }
else
{
riscv_subset_t *isubset = NULL;
@@ -2501,13 +2568,10 @@ riscv_update_subset1 (riscv_parse_subset_t *rps,
}
while (*p++ == ',');
- bool conflict = false;
- if (explicit_subset == NULL)
- {
- riscv_parse_add_implicit_subsets (rps);
- conflict = riscv_parse_check_conflicts (rps);
- }
- return conflict;
+ if (behavior == SUB)
+ riscv_update_superset (rps);
+
+ return true;
}
/* Add/Remove an extension to/from the subset list. This is used for
@@ -2517,7 +2581,9 @@ bool
riscv_update_subset (riscv_parse_subset_t *rps,
const char *str)
{
- return riscv_update_subset1 (rps, NULL, str);
+ riscv_update_subset1 (rps, str);
+ riscv_parse_add_implicit_subsets (rps);
+ return riscv_parse_check_conflicts (rps);
}
/* Check if the FEATURE subset is supported or not in the subset list.
@@ -2556,10 +2622,9 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
return riscv_subset_supports (rps, "zifencei");
case INSN_CLASS_ZIHINTNTL:
return riscv_subset_supports (rps, "zihintntl");
- case INSN_CLASS_ZIHINTNTL_AND_C:
+ case INSN_CLASS_ZIHINTNTL_AND_ZCA:
return (riscv_subset_supports (rps, "zihintntl")
- && (riscv_subset_supports (rps, "c")
- || riscv_subset_supports (rps, "zca")));
+ && riscv_subset_supports (rps, "zca"));
case INSN_CLASS_ZIHINTPAUSE:
return riscv_subset_supports (rps, "zihintpause");
case INSN_CLASS_ZIMOP:
@@ -2587,17 +2652,12 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
return riscv_subset_supports (rps, "d");
case INSN_CLASS_Q:
return riscv_subset_supports (rps, "q");
- case INSN_CLASS_C:
- return (riscv_subset_supports (rps, "c")
- || riscv_subset_supports (rps, "zca"));
- case INSN_CLASS_F_AND_C:
- return (riscv_subset_supports (rps, "f")
- && (riscv_subset_supports (rps, "c")
- || riscv_subset_supports (rps, "zcf")));
- case INSN_CLASS_D_AND_C:
- return (riscv_subset_supports (rps, "d")
- && (riscv_subset_supports (rps, "c")
- || riscv_subset_supports (rps, "zcd")));
+ case INSN_CLASS_ZCA:
+ return riscv_subset_supports (rps, "zca");
+ case INSN_CLASS_ZCF:
+ return riscv_subset_supports (rps, "zcf");
+ case INSN_CLASS_ZCD:
+ return riscv_subset_supports (rps, "zcd");
case INSN_CLASS_F_INX:
return (riscv_subset_supports (rps, "f")
|| riscv_subset_supports (rps, "zfinx"));
@@ -2804,17 +2864,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return "zifencei";
case INSN_CLASS_ZIHINTNTL:
return "zihintntl";
- case INSN_CLASS_ZIHINTNTL_AND_C:
- if (!riscv_subset_supports (rps, "zihintntl"))
- {
- if (!riscv_subset_supports (rps, "c")
- && !riscv_subset_supports (rps, "zca"))
- return _("zihintntl' and `c', or `zihintntl' and `zca");
- else
- return "zihintntl";
- }
- else
- return _("c' or `zca");
+ case INSN_CLASS_ZIHINTNTL_AND_ZCA:
+ return _("zihintntl' and `zca");
case INSN_CLASS_ZIHINTPAUSE:
return "zihintpause";
case INSN_CLASS_ZIMOP:
@@ -2822,7 +2873,7 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
case INSN_CLASS_M:
return "m";
case INSN_CLASS_ZMMUL:
- return _ ("m' or `zmmul");
+ return "zmmul";
case INSN_CLASS_ZAAMO:
return "zaamo";
case INSN_CLASS_ZABHA:
@@ -2839,30 +2890,12 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return "d";
case INSN_CLASS_Q:
return "q";
- case INSN_CLASS_C:
- return _("c' or `zca");
- case INSN_CLASS_F_AND_C:
- if (!riscv_subset_supports (rps, "f"))
- {
- if (!riscv_subset_supports (rps, "c")
- && !riscv_subset_supports (rps, "zcf"))
- return _("f' and `c', or `f' and `zcf");
- else
- return "f";
- }
- else
- return _("c' or `zcf");
- case INSN_CLASS_D_AND_C:
- if (!riscv_subset_supports (rps, "d"))
- {
- if (!riscv_subset_supports (rps, "c")
- && !riscv_subset_supports (rps, "zcd"))
- return _("d' and `c', or `d' and `zcd");
- else
- return "d";
- }
- else
- return _("c' or `zcd");
+ case INSN_CLASS_ZCA:
+ return "zca";
+ case INSN_CLASS_ZCF:
+ return "zcf";
+ case INSN_CLASS_ZCD:
+ return "zcd";
case INSN_CLASS_F_INX:
return _("f' or `zfinx");
case INSN_CLASS_D_INX:
@@ -2997,7 +3030,7 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
case INSN_CLASS_ZCB_AND_ZBB:
return _("zcb' and `zbb");
case INSN_CLASS_ZCB_AND_ZMMUL:
- return _("zcb' and `zmmul', or `zcb' and `m");
+ return _("zcb' and `zmmul");
case INSN_CLASS_ZCMOP:
return "zcmop";
case INSN_CLASS_ZCMP:
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index e19142dca19..14dfd41dcfc 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -367,8 +367,7 @@ riscv_set_arch (const char *s)
riscv_set_arch_str (&file_arch_str);
riscv_set_arch_str (&riscv_rps_as.subset_list->arch_str);
- riscv_set_rvc (riscv_subset_supports (&riscv_rps_as, "c")
- || riscv_subset_supports (&riscv_rps_as, "zca"));
+ riscv_set_rvc (riscv_subset_supports (&riscv_rps_as, "zca"));
if (riscv_subset_supports (&riscv_rps_as, "ztso"))
riscv_set_tso ();
@@ -4934,8 +4933,7 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
riscv_update_subset (&riscv_rps_as, name);
riscv_set_arch_str (&riscv_rps_as.subset_list->arch_str);
- riscv_set_rvc (riscv_subset_supports (&riscv_rps_as, "c")
- || riscv_subset_supports (&riscv_rps_as, "zca"));
+ riscv_set_rvc (riscv_subset_supports (&riscv_rps_as, "zca"));
if (riscv_subset_supports (&riscv_rps_as, "ztso"))
riscv_set_tso ();
diff --git a/gas/testsuite/gas/riscv/attribute-10.d b/gas/testsuite/gas/riscv/attribute-10.d
index 04c322ab1dd..cb3ae5a897f 100644
--- a/gas/testsuite/gas/riscv/attribute-10.d
+++ b/gas/testsuite/gas/riscv/attribute-10.d
@@ -3,4 +3,4 @@
#source: empty.s
Attribute Section: riscv
File Attributes
- Tag_RISCV_arch: "rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0"
+ Tag_RISCV_arch: "rv32i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zcf1p0"
diff --git a/gas/testsuite/gas/riscv/imply.d b/gas/testsuite/gas/riscv/imply.d
index 26eff8c650a..f974eac188a 100644
--- a/gas/testsuite/gas/riscv/imply.d
+++ b/gas/testsuite/gas/riscv/imply.d
@@ -64,6 +64,11 @@ SYMBOL TABLE:
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_f2p2_zicsr2p0_zfhmin1p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zicsr2p0_zfinx1p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_f2p2_zicsr2p0
+[0-9a-f]+ l .text 0+000 \$xrv32i2p1_c2p0_zca1p0
+[0-9a-f]+ l .text 0+000 \$xrv32i2p1_f2p2_c2p0_zicsr2p0_zca1p0_zcf1p0
+[0-9a-f]+ l .text 0+000 \$xrv64i2p1_f2p2_c2p0_zicsr2p0_zca1p0
+[0-9a-f]+ l .text 0+000 \$xrv32i2p1_f2p2_d2p2_c2p0_zicsr2p0_zca1p0_zcd1p0_zcf1p0
+[0-9a-f]+ l .text 0+000 \$xrv64i2p1_f2p2_d2p2_c2p0_zicsr2p0_zca1p0_zcd1p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_b1p0_zba1p0_zbb1p0_zbs1p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zbkb1p0_zbkc1p0_zbkx1p0_zk1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zbkb1p0_zbkc1p0_zbkx1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0
diff --git a/gas/testsuite/gas/riscv/imply.s b/gas/testsuite/gas/riscv/imply.s
index dabb08d8c8b..31664b9b6ac 100644
--- a/gas/testsuite/gas/riscv/imply.s
+++ b/gas/testsuite/gas/riscv/imply.s
@@ -1,15 +1,15 @@
-.macro imply string base=i
+.macro imply string xlen=32 base=i
.option push
-.option arch, rv32\base\string
+.option arch, rv\xlen\base\string
nop
.option pop
.endm
.text
-imply ,g
-imply ,e
-imply ,i
-imply ,i2p0
+imply ,,g
+imply ,,e
+imply ,,i
+imply ,,i2p0
imply zicntr
imply zihpm
@@ -72,6 +72,12 @@ imply zfhmin
imply zfinx
imply f
+imply c
+imply f_c,32
+imply f_c,64
+imply d_c,32
+imply d_c,64
+
imply b
imply zk
diff --git a/gas/testsuite/gas/riscv/m-ext-fail-noarch-64.l b/gas/testsuite/gas/riscv/m-ext-fail-noarch-64.l
index db9c8fb8396..b646c3b16ef 100644
--- a/gas/testsuite/gas/riscv/m-ext-fail-noarch-64.l
+++ b/gas/testsuite/gas/riscv/m-ext-fail-noarch-64.l
@@ -1,13 +1,13 @@
.*Assembler messages:
-.*: Error: unrecognized opcode `mul a0,a1,a2', extension `m' or `zmmul' required
-.*: Error: unrecognized opcode `mulh a0,a1,a2', extension `m' or `zmmul' required
-.*: Error: unrecognized opcode `mulhsu a0,a1,a2', extension `m' or `zmmul' required
-.*: Error: unrecognized opcode `mulhu a0,a1,a2', extension `m' or `zmmul' required
+.*: Error: unrecognized opcode `mul a0,a1,a2', extension `zmmul' required
+.*: Error: unrecognized opcode `mulh a0,a1,a2', extension `zmmul' required
+.*: Error: unrecognized opcode `mulhsu a0,a1,a2', extension `zmmul' required
+.*: Error: unrecognized opcode `mulhu a0,a1,a2', extension `zmmul' required
.*: Error: unrecognized opcode `div a0,a1,a2', extension `m' required
.*: Error: unrecognized opcode `divu a0,a1,a2', extension `m' required
.*: Error: unrecognized opcode `rem a0,a1,a2', extension `m' required
.*: Error: unrecognized opcode `remu a0,a1,a2', extension `m' required
-.*: Error: unrecognized opcode `mulw a0,a1,a2', extension `m' or `zmmul' required
+.*: Error: unrecognized opcode `mulw a0,a1,a2', extension `zmmul' required
.*: Error: unrecognized opcode `divw a0,a1,a2', extension `m' required
.*: Error: unrecognized opcode `divuw a0,a1,a2', extension `m' required
.*: Error: unrecognized opcode `remw a0,a1,a2', extension `m' required
diff --git a/gas/testsuite/gas/riscv/mapping-symbols.d b/gas/testsuite/gas/riscv/mapping-symbols.d
index 057454bf991..f7d5b6f4d0c 100644
--- a/gas/testsuite/gas/riscv/mapping-symbols.d
+++ b/gas/testsuite/gas/riscv/mapping-symbols.d
@@ -9,44 +9,44 @@ SYMBOL TABLE:
0+00 l d .data 0+00 .data
0+00 l d .bss 0+00 .bss
0+00 l d .text.cross.section.A 0+00 .text.cross.section.A
-0+00 l .text.cross.section.A 0+00 \$xrv32i2p1_c2p0
+0+00 l .text.cross.section.A 0+00 \$xrv32i2p1_c2p0_zca1p0
0+00 l d .text.cross.section.B 0+00 .text.cross.section.B
-0+00 l .text.cross.section.B 0+00 \$xrv32i2p1_c2p0
+0+00 l .text.cross.section.B 0+00 \$xrv32i2p1_c2p0_zca1p0
0+02 l .text.cross.section.B 0+00 \$xrv32i2p1
0+00 l d .text.data 0+00 .text.data
0+00 l .text.data 0+00 \$d
-0+08 l .text.data 0+00 \$xrv32i2p1_c2p0
+0+08 l .text.data 0+00 \$xrv32i2p1_c2p0_zca1p0
0+0c l .text.data 0+00 \$d
0+00 l d .text.odd.align.start.insn 0+00 .text.odd.align.start.insn
-0+00 l .text.odd.align.start.insn 0+00 \$xrv32i2p1_c2p0
+0+00 l .text.odd.align.start.insn 0+00 \$xrv32i2p1_c2p0_zca1p0
0+02 l .text.odd.align.start.insn 0+00 \$d
0+08 l .text.odd.align.start.insn 0+00 \$xrv32i2p1
0+00 l d .text.odd.align.start.data 0+00 .text.odd.align.start.data
0+00 l .text.odd.align.start.data 0+00 \$d
0+00 l d .text.zero.fill.first 0+00 .text.zero.fill.first
-0+00 l .text.zero.fill.first 0+00 \$xrv32i2p1_c2p0
+0+00 l .text.zero.fill.first 0+00 \$xrv32i2p1_c2p0_zca1p0
0+00 l d .text.zero.fill.last 0+00 .text.zero.fill.last
-0+00 l .text.zero.fill.last 0+00 \$xrv32i2p1_c2p0
+0+00 l .text.zero.fill.last 0+00 \$xrv32i2p1_c2p0_zca1p0
0+02 l .text.zero.fill.last 0+00 \$x
0+00 l d .text.zero.fill.align.A 0+00 .text.zero.fill.align.A
-0+00 l .text.zero.fill.align.A 0+00 \$xrv32i2p1_c2p0
+0+00 l .text.zero.fill.align.A 0+00 \$xrv32i2p1_c2p0_zca1p0
0+00 l d .text.zero.fill.align.B 0+00 .text.zero.fill.align.B
0+00 l .text.zero.fill.align.B 0+00 \$xrv32i2p1
0+00 l d .text.last.section 0+00 .text.last.section
0+00 l .text.last.section 0+00 \$xrv32i2p1
0+04 l .text.last.section 0+00 \$d
0+00 l d .text.section.padding 0+00 .text.section.padding
-0+00 l .text.section.padding 0+00 \$xrv32i2p1_c2p0
-0+04 l .text.section.padding 0+00 \$xrv32i2p1_a2p1_c2p0_zaamo1p0_zalrsc1p0
+0+00 l .text.section.padding 0+00 \$xrv32i2p1_c2p0_zca1p0
+0+04 l .text.section.padding 0+00 \$xrv32i2p1_a2p1_c2p0_zaamo1p0_zalrsc1p0_zca1p0
0+06 l .text.section.padding 0+00 \$d
0+00 l d .text.relax.align 0+00 .text.relax.align
-0+00 l .text.relax.align 0+00 \$xrv32i2p1_c2p0
+0+00 l .text.relax.align 0+00 \$xrv32i2p1_c2p0_zca1p0
0+08 l .text.relax.align 0+00 \$xrv32i2p1
0+0a l .text.section.padding 0+00 \$x
0+03 l .text.odd.align.start.insn 0+00 \$d
0+04 l .text.odd.align.start.insn 0+00 \$x
0+01 l .text.odd.align.start.data 0+00 \$d
-0+02 l .text.odd.align.start.data 0+00 \$xrv32i2p1_c2p0
+0+02 l .text.odd.align.start.data 0+00 \$xrv32i2p1_c2p0_zca1p0
0+00 l d .riscv.attributes 0+00 .riscv.attributes
0+00 g .text.cross.section.A 0+00 funcA
0+00 g .text.cross.section.B 0+00 funcB
diff --git a/gas/testsuite/gas/riscv/march-ok-reorder.d b/gas/testsuite/gas/riscv/march-ok-reorder.d
index 712c1bdff4d..883d6a2e1cd 100644
--- a/gas/testsuite/gas/riscv/march-ok-reorder.d
+++ b/gas/testsuite/gas/riscv/march-ok-reorder.d
@@ -4,4 +4,4 @@
Attribute Section: riscv
File Attributes
- Tag_RISCV_arch: "rv32i2p0_m1p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zba1p0_xbar2p0_xfoo2p0"
+ Tag_RISCV_arch: "rv32i2p0_m1p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0_zcf1p0_zba1p0_xbar2p0_xfoo2p0"
diff --git a/gas/testsuite/gas/riscv/option-arch-attr.d b/gas/testsuite/gas/riscv/option-arch-attr.d
index 8c1f6658796..27df69dc176 100644
--- a/gas/testsuite/gas/riscv/option-arch-attr.d
+++ b/gas/testsuite/gas/riscv/option-arch-attr.d
@@ -4,4 +4,4 @@
Attribute Section: riscv
File Attributes
- Tag_RISCV_arch: "rv64i2p0_c2p0"
+ Tag_RISCV_arch: "rv64i2p0_c2p0_zca1p0"
diff --git a/gas/testsuite/gas/riscv/option-arch-dis.d b/gas/testsuite/gas/riscv/option-arch-dis.d
index 6768fe72806..980312fcdb1 100644
--- a/gas/testsuite/gas/riscv/option-arch-dis.d
+++ b/gas/testsuite/gas/riscv/option-arch-dis.d
@@ -8,10 +8,10 @@ SYMBOL TABLE:
0+00 l d .text 0+00 .text
0+00 l d .data 0+00 .data
0+00 l d .bss 0+00 .bss
-0+00 l .text 0+00 \$xrv64i2p0_c2p0
+0+00 l .text 0+00 \$xrv64i2p0_c2p0_zca1p0
0+02 l .text 0+00 \$xrv64i2p0_f2p0_d2p0_xvendor1p0
-0+0a l .text 0+00 \$xrv64i2p0_m3p0_f2p0_d3p0_c2p0_zmmul1p0_xvendor32x3p0
-0+0c l .text 0+00 \$xrv32i2p1_c2p0
+0+0a l .text 0+00 \$xrv64i2p0_m3p0_f2p0_d3p0_c2p0_zmmul1p0_zca1p0_zcd1p0_xvendor32x3p0
+0+0c l .text 0+00 \$xrv32i2p1_c2p0_zca1p0
0+00 l d .riscv.attributes 0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/option-arch-fail.l b/gas/testsuite/gas/riscv/option-arch-fail.l
index b9979a42618..52625123561 100644
--- a/gas/testsuite/gas/riscv/option-arch-fail.l
+++ b/gas/testsuite/gas/riscv/option-arch-fail.l
@@ -1,10 +1,11 @@
.*Assembler messages:
.*Error: m2p0: ISA string must begin with rv32 or rv64
-.*Error: cannot \+ or \- base extension `i' in .option arch `\-i'
-.*Error: cannot \+ or \- base extension `e' in .option arch `\+e'
-.*Error: cannot \+ or \- base extension `g' in .option arch `\-g'
-.*Error: unknown ISA extension `zsubset' in .option arch `\+zsubset2p0'
-.*Error: unknown ISA extension `f2p0_d' in .option arch `\+f2p0_d2p0'
-.*Error: unknown ISA extension `' in .option arch `\+'
-.*Error: invalid ISA extension ends with <number>p in .option arch `\+xvendor2p'
+.*Error: \-i: cannot remove base extension `i'
+.*Error: \-e: cannot remove base extension `e'
+.*Error: \-g: cannot remove base extension `g'
+.*Error: \+zsubset2p0: unknown prefixed ISA extension `zsubset'
+.*Error: \+f2p0_d2p0: unknown prefixed ISA extension `f2p0_d'
+.*Error: \+: unknown ISA extension `'
+.*Error: \+xvendor2p: invalid prefixed ISA extension `xvendor2p' ends with <number>p
+.*Error: \+c,\-c: cannot mix `\+' and `\-' at the same time
.*Error: .option pop with no .option push
diff --git a/gas/testsuite/gas/riscv/option-arch-fail.s b/gas/testsuite/gas/riscv/option-arch-fail.s
index 101587aee16..47b469b712f 100644
--- a/gas/testsuite/gas/riscv/option-arch-fail.s
+++ b/gas/testsuite/gas/riscv/option-arch-fail.s
@@ -2,11 +2,12 @@
.option push
.option arch, m2p0
.option arch, -i
-.option arch, +e
+.option arch, -e
.option arch, -g
.option arch, +zsubset2p0
.option arch, +f2p0_d2p0
.option arch, +
.option arch, +xvendor2p
+.option arch, +c,-c
.option pop
.option pop
diff --git a/gas/testsuite/gas/riscv/option-arch-superset.d b/gas/testsuite/gas/riscv/option-arch-superset.d
new file mode 100644
index 00000000000..b721428b95c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/option-arch-superset.d
@@ -0,0 +1,154 @@
+#as: -misa-spec=20191213
+#source: option-arch-superset.s
+#objdump: --syms --special-syms
+
+.*:[ ]+file format .*
+
+SYMBOL TABLE:
+[0-9a-f]+ l d .text 0+00 .text
+[0-9a-f]+ l d .data 0+00 .data
+[0-9a-f]+ l d .bss 0+00 .bss
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_m2p0_zmmul1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvbb1p0_zvkb1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zicsr2p0_zfinx1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zicsr2p0_zfinx1p0_zhinx1p0_zhinxmin1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zicsr2p0_zfinx1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_f2p2_zicsr2p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_f2p2_zicsr2p0_zfh1p0_zfhmin1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_f2p2_zicsr2p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zalrsc1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zaamo1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbb1p0_zbs1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zba1p0_zbs1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zba1p0_zbb1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkc1p0_zbkx1p0_zksed1p0_zksh1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkx1p0_zksed1p0_zksh1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkc1p0_zksed1p0_zksh1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkc1p0_zbkx1p0_zksh1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkc1p0_zbkx1p0_zksed1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkc1p0_zbkx1p0_zknd1p0_zkne1p0_zknh1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkx1p0_zknd1p0_zkne1p0_zknh1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkc1p0_zknd1p0_zkne1p0_zknh1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkc1p0_zbkx1p0_zknd1p0_zknh1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkc1p0_zbkx1p0_zkne1p0_zknh1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkc1p0_zbkx1p0_zknd1p0_zkne1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkc1p0_zbkx1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkx1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkc1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkc1p0_zbkx1p0_zknd1p0_zknh1p0_zkr1p0_zkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkc1p0_zbkx1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkc1p0_zbkx1p0_zknd1p0_zkne1p0_zkr1p0_zkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zkr1p0_zkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkc1p0_zbkx1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zbkb1p0_zbkc1p0_zbkx1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkned1p0_zvknhb1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvkned1p0_zvknhb1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvknhb1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvkned1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvksed1p0_zvksh1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvksed1p0_zvksh1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvksh1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvksed1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkg1p0_zvkned1p0_zvknhb1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvkg1p0_zvkned1p0_zvknhb1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvkg1p0_zvknhb1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvkg1p0_zvkned1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkg1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvkn1p0_zvkned1p0_zvknhb1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvbc1p0_zvkned1p0_zvknhb1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvbc1p0_zvkb1p0_zvkned1p0_zvknhb1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvbc1p0_zvkb1p0_zvknhb1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvbc1p0_zvkb1p0_zvkned1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvbc1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvkn1p0_zvkned1p0_zvknhb1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkg1p0_zvksed1p0_zvksh1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvkg1p0_zvksed1p0_zvksh1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvkg1p0_zvksh1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvkg1p0_zvksed1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkg1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvks1p0_zvksed1p0_zvksh1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvbc1p0_zvksed1p0_zvksh1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvbc1p0_zvkb1p0_zvksed1p0_zvksh1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvbc1p0_zvkb1p0_zvksh1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvbc1p0_zvkb1p0_zvksed1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvbc1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_zvkb1p0_zvks1p0_zvksed1p0_zvksh1p0_zvkt1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_c2p0_zca1p0
+[0-9a-f]+ l .text 0+00 \$xrv64i2p1
+[0-9a-f]+ l .text 0+00 \$xrv64i2p1_c2p0_zca1p0
+[0-9a-f]+ l .text 0+00 \$xrv64i2p1_f2p2_zicsr2p0
+[0-9a-f]+ l .text 0+00 \$xrv64i2p1_f2p2_c2p0_zicsr2p0_zca1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_f2p2_zicsr2p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_f2p2_zicsr2p0_zca1p0_zcf1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_f2p2_zicsr2p0_zca1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_f2p2_c2p0_zicsr2p0_zca1p0_zcf1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_f2p2_d2p2_zicsr2p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_f2p2_d2p2_zicsr2p0_zca1p0_zcd1p0_zcf1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_f2p2_d2p2_zicsr2p0_zca1p0_zcd1p0
+[0-9a-f]+ l .text 0+00 \$xrv32i2p1_f2p2_d2p2_zicsr2p0_zca1p0_zcf1p0
+[0-9a-f]+ l .text 0+00 \$xrv64i2p1_f2p2_d2p2_zicsr2p0
+[0-9a-f]+ l .text 0+00 \$xrv64i2p1_f2p2_d2p2_zicsr2p0_zca1p0_zcd1p0
+[0-9a-f]+ l .text 0+00 \$xrv64i2p1_f2p2_d2p2_c2p0_zicsr2p0_zca1p0_zcd1p0
+[0-9a-f]+ l .text 0+00 \$xrv64i2p1_f2p2_d2p2_zicsr2p0_zca1p0
+[0-9a-f]+ l d .riscv.attributes 0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/option-arch-superset.s b/gas/testsuite/gas/riscv/option-arch-superset.s
new file mode 100644
index 00000000000..2691b11ce20
--- /dev/null
+++ b/gas/testsuite/gas/riscv/option-arch-superset.s
@@ -0,0 +1,180 @@
+.macro case superset subset
+.option arch, rv32i_\superset
+.option arch, -\superset
+nop
+.option arch, rv32i_\superset
+.option arch, -\subset
+nop
+.option arch, rv32i\subset
+.option arch, -\superset
+nop
+.endm
+
+.text
+
+# Superset > Subset
+# Remove the Subset is useless
+
+case m, zmmul
+case zvbb, zvkb
+case zhinx, zhinxmin
+case zfh, zfhmin
+
+# Superset = Subset1 + Subset2 + ...
+# Also remove the Superset when removing Subset1, or/and Subset2 ...
+
+# a = zaamo + zalrsc
+case a, zaamo
+case a, zalrsc
+
+# b = zba + zbb + zbs
+case b, zba
+case b, zbb
+case b, zbs
+
+# zks = zbkb + zbkc + zbkx + zksed + zksh
+case zks, zbkb
+case zks, zbkc
+case zks, zbkx
+case zks, zksed
+case zks, zksh
+
+# zkn = zbkb + zbkc + zbkx + zkne + zknd + zknh
+case zkn, zbkb
+case zkn, zbkc
+case zkn, zbkx
+case zkn, zkne
+case zkn, zknd
+case zkn, zknh
+
+# zk = zkn + zkr + zkt
+case zk, zbkb
+case zk, zbkc
+case zk, zbkx
+case zk, zkne
+case zk, zknd
+case zk, zknh
+case zk, zkn
+case zk, zkr
+case zk, zkt
+
+# zvkn = zvkb + zvkt + zvkned + zvknhb
+case zvkn, zvkb
+case zvkn, zvkt
+case zvkn, zvkned
+case zvkn, zvknhb
+
+# zvks = zvkb + zvkt + zvksed + zvksh
+case zvks, zvkb
+case zvks, zvkt
+case zvks, zvksed
+case zvks, zvksh
+
+# zvkng = zvkn + zvkg
+case zvkng, zvkb
+case zvkng, zvkt
+case zvkng, zvkned
+case zvkng, zvknhb
+case zvkng, zvkn
+case zvkng, zvkg
+
+# zvknc = zvkn + zvbc
+case zvknc, zvkb
+case zvknc, zvkt
+case zvknc, zvkned
+case zvknc, zvknhb
+case zvknc, zvkn
+case zvknc, zvbc
+
+# zvksg = zvks + zvkg
+case zvksg, zvkb
+case zvksg, zvkt
+case zvksg, zvksed
+case zvksg, zvksh
+case zvksg, zvks
+case zvksg, zvkg
+
+# zvksc = zvks + zvbc
+case zvksc, zvkb
+case zvksc, zvkt
+case zvksc, zvksed
+case zvksc, zvksh
+case zvksc, zvks
+case zvksc, zvbc
+
+# c = zca
+# rv32ic_zca
+.option arch, rv32ic
+.option arch, -c
+nop # rv32i
+.option arch, rv32ic
+.option arch, -zca
+nop # rv32i
+.option arch, rv32ic
+.option arch, -zcf,-zcd
+nop # rv32ic_zca, -zcf and zcd are useless since c = zca
+# rv64ic_zca
+.option arch, rv64ic
+.option arch, -c
+nop # rv64i
+.option arch, rv64ic
+.option arch, -zca
+nop # rv64i
+.option arch, rv64ic
+.option arch, -zcf,-zcd
+nop # rv64ic_zca, -zcf and zcd are useless since c = zca
+# rv64ifc_zicsr_zca
+.option arch, rv64ifc
+.option arch, -c
+nop # rv64if_zicsr
+.option arch, rv64ifc
+.option arch, -zca
+nop # rv64if_zicsr
+.option arch, rv64ifc
+.option arch, -zcf,-zcd
+nop # rv64ifc_zicsr_zca, -zcf and zcd are useless since c = zca
+
+# c = zca + zcf (if f and rv32)
+# rv32ifc_zicsr_zca_zcf
+.option arch, rv32ifc
+.option arch, -c
+nop # rv32if_zicsr
+.option arch, rv32ifc
+.option arch, -zca
+nop # rv32if_zicsr_zca_zcf, zcf imply zca
+.option arch, rv32ifc
+.option arch, -zcf
+nop # rv32if_zicsr_zca
+.option arch, rv32ifc
+.option arch, -zcd
+nop # rv32ifc_zicsr_zca_zcf, -zcd is useless since c = zca + zcf
+
+# c = zca + zcf (if f and rv32) + zcd (if d)
+# rv32ifdc_zicsr_zca_zcd_zcf
+.option arch, rv32ifdc
+.option arch, -c
+nop # rv32ifd_zicsr
+.option arch, rv32ifdc
+.option arch, -zca
+nop # rv32ifd_zicsr_zca_zcd_zcf, zcf and zcd imply zca
+.option arch, rv32ifdc
+.option arch, -zcf
+nop # rv32ifd_zicsr_zca_zcd
+.option arch, rv32ifdc
+.option arch, -zcd
+nop # rv32ifd_zicsr_zca_zcf
+
+# c = zca + zcd (if d)
+# rv64ifdc_zicsr_zca_zcd
+.option arch, rv64ifdc
+.option arch, -c
+nop # rv64ifd_zicsr
+.option arch, rv64ifdc
+.option arch, -zca
+nop # rv64ifd_zicsr_zca_zcd, zcd imply zca
+.option arch, rv64ifdc
+.option arch, -zcf
+nop # rv64ifdc_zicsr_zca_zcd, -zcf is useless since c = zca + zcd
+.option arch, rv64ifdc
+.option arch, -zcd
+nop # rv64ifd_zicsr_zca
diff --git a/gas/testsuite/gas/riscv/option-arch.s b/gas/testsuite/gas/riscv/option-arch.s
index 4d2d261684a..53f919149aa 100644
--- a/gas/testsuite/gas/riscv/option-arch.s
+++ b/gas/testsuite/gas/riscv/option-arch.s
@@ -1,7 +1,8 @@
.attribute arch, "rv64ic" # file-level, rv64ic
add a0, a0, a1
.option push
-.option arch, +d2p0, -c, +xvendor1p0
+.option arch, +d2p0, +xvendor1p0
+.option arch, -c
add a0, a0, a1 # func-level, rv64i_d2p0_xvendor1p0
frcsr a0
.option pop
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 7df15174d60..2d9fb541503 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -452,18 +452,18 @@ enum riscv_insn_class
INSN_CLASS_NONE,
INSN_CLASS_I,
- INSN_CLASS_C,
+ INSN_CLASS_ZCA,
INSN_CLASS_M,
INSN_CLASS_F,
INSN_CLASS_D,
INSN_CLASS_Q,
- INSN_CLASS_F_AND_C,
- INSN_CLASS_D_AND_C,
+ INSN_CLASS_ZCF,
+ INSN_CLASS_ZCD,
INSN_CLASS_ZICOND,
INSN_CLASS_ZICSR,
INSN_CLASS_ZIFENCEI,
INSN_CLASS_ZIHINTNTL,
- INSN_CLASS_ZIHINTNTL_AND_C,
+ INSN_CLASS_ZIHINTNTL_AND_ZCA,
INSN_CLASS_ZIHINTPAUSE,
INSN_CLASS_ZIMOP,
INSN_CLASS_ZMMUL,
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 8d5c574da6e..a1f847ae3ff 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -380,34 +380,34 @@ const struct riscv_opcode riscv_opcodes[] =
{"prefetch.i", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_I, MASK_PREFETCH_I, match_opcode, 0 },
{"prefetch.r", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_R, MASK_PREFETCH_R, match_opcode, 0 },
{"prefetch.w", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_W, MASK_PREFETCH_W, match_opcode, 0 },
-{"ntl.p1", 0, INSN_CLASS_ZIHINTNTL_AND_C, "", MATCH_C_NTL_P1, MASK_C_NTL_P1, match_opcode, INSN_ALIAS },
+{"ntl.p1", 0, INSN_CLASS_ZIHINTNTL_AND_ZCA, "", MATCH_C_NTL_P1, MASK_C_NTL_P1, match_opcode, INSN_ALIAS },
{"ntl.p1", 0, INSN_CLASS_ZIHINTNTL, "", MATCH_NTL_P1, MASK_NTL_P1, match_opcode, 0 },
-{"ntl.pall", 0, INSN_CLASS_ZIHINTNTL_AND_C, "", MATCH_C_NTL_PALL, MASK_C_NTL_PALL, match_opcode, INSN_ALIAS },
+{"ntl.pall", 0, INSN_CLASS_ZIHINTNTL_AND_ZCA, "", MATCH_C_NTL_PALL, MASK_C_NTL_PALL, match_opcode, INSN_ALIAS },
{"ntl.pall", 0, INSN_CLASS_ZIHINTNTL, "", MATCH_NTL_PALL, MASK_NTL_PALL, match_opcode, 0 },
-{"ntl.s1", 0, INSN_CLASS_ZIHINTNTL_AND_C, "", MATCH_C_NTL_S1, MASK_C_NTL_S1, match_opcode, INSN_ALIAS },
+{"ntl.s1", 0, INSN_CLASS_ZIHINTNTL_AND_ZCA, "", MATCH_C_NTL_S1, MASK_C_NTL_S1, match_opcode, INSN_ALIAS },
{"ntl.s1", 0, INSN_CLASS_ZIHINTNTL, "", MATCH_NTL_S1, MASK_NTL_S1, match_opcode, 0 },
-{"ntl.all", 0, INSN_CLASS_ZIHINTNTL_AND_C, "", MATCH_C_NTL_ALL, MASK_C_NTL_ALL, match_opcode, INSN_ALIAS },
+{"ntl.all", 0, INSN_CLASS_ZIHINTNTL_AND_ZCA, "", MATCH_C_NTL_ALL, MASK_C_NTL_ALL, match_opcode, INSN_ALIAS },
{"ntl.all", 0, INSN_CLASS_ZIHINTNTL, "", MATCH_NTL_ALL, MASK_NTL_ALL, match_opcode, 0 },
-{"c.ntl.p1", 0, INSN_CLASS_ZIHINTNTL_AND_C, "", MATCH_C_NTL_P1, MASK_C_NTL_P1, match_opcode, 0 },
-{"c.ntl.pall", 0, INSN_CLASS_ZIHINTNTL_AND_C, "", MATCH_C_NTL_PALL, MASK_C_NTL_PALL, match_opcode, 0 },
-{"c.ntl.s1", 0, INSN_CLASS_ZIHINTNTL_AND_C, "", MATCH_C_NTL_S1, MASK_C_NTL_S1, match_opcode, 0 },
-{"c.ntl.all", 0, INSN_CLASS_ZIHINTNTL_AND_C, "", MATCH_C_NTL_ALL, MASK_C_NTL_ALL, match_opcode, 0 },
+{"c.ntl.p1", 0, INSN_CLASS_ZIHINTNTL_AND_ZCA, "", MATCH_C_NTL_P1, MASK_C_NTL_P1, match_opcode, 0 },
+{"c.ntl.pall", 0, INSN_CLASS_ZIHINTNTL_AND_ZCA, "", MATCH_C_NTL_PALL, MASK_C_NTL_PALL, match_opcode, 0 },
+{"c.ntl.s1", 0, INSN_CLASS_ZIHINTNTL_AND_ZCA, "", MATCH_C_NTL_S1, MASK_C_NTL_S1, match_opcode, 0 },
+{"c.ntl.all", 0, INSN_CLASS_ZIHINTNTL_AND_ZCA, "", MATCH_C_NTL_ALL, MASK_C_NTL_ALL, match_opcode, 0 },
{"pause", 0, INSN_CLASS_ZIHINTPAUSE, "", MATCH_PAUSE, MASK_PAUSE, match_opcode, 0 },
/* Basic RVI instructions and aliases. */
-{"unimp", 0, INSN_CLASS_C, "", 0, 0xffffU, match_opcode, INSN_ALIAS },
+{"unimp", 0, INSN_CLASS_ZCA, "", 0, 0xffffU, match_opcode, INSN_ALIAS },
{"unimp", 0, INSN_CLASS_I, "", MATCH_CSRRW|(CSR_CYCLE << OP_SH_CSR), 0xffffffffU, match_opcode, 0 }, /* csrw cycle, x0 */
-{"ebreak", 0, INSN_CLASS_C, "", MATCH_C_EBREAK, MASK_C_EBREAK, match_opcode, INSN_ALIAS },
+{"ebreak", 0, INSN_CLASS_ZCA, "", MATCH_C_EBREAK, MASK_C_EBREAK, match_opcode, INSN_ALIAS },
{"ebreak", 0, INSN_CLASS_I, "", MATCH_EBREAK, MASK_EBREAK, match_opcode, 0 },
-{"sbreak", 0, INSN_CLASS_C, "", MATCH_C_EBREAK, MASK_C_EBREAK, match_opcode, INSN_ALIAS },
+{"sbreak", 0, INSN_CLASS_ZCA, "", MATCH_C_EBREAK, MASK_C_EBREAK, match_opcode, INSN_ALIAS },
{"sbreak", 0, INSN_CLASS_I, "", MATCH_EBREAK, MASK_EBREAK, match_opcode, INSN_ALIAS },
-{"ret", 0, INSN_CLASS_C, "", MATCH_C_JR|(X_RA << OP_SH_RD), MASK_C_JR|MASK_RD, match_opcode, INSN_ALIAS|INSN_BRANCH },
+{"ret", 0, INSN_CLASS_ZCA, "", MATCH_C_JR|(X_RA << OP_SH_RD), MASK_C_JR|MASK_RD, match_opcode, INSN_ALIAS|INSN_BRANCH },
{"ret", 0, INSN_CLASS_I, "", MATCH_JALR|(X_RA << OP_SH_RS1), MASK_JALR|MASK_RD|MASK_RS1|MASK_IMM, match_opcode, INSN_ALIAS|INSN_BRANCH },
-{"jr", 0, INSN_CLASS_C, "d", MATCH_C_JR, MASK_C_JR, match_rd_nonzero, INSN_ALIAS|INSN_BRANCH },
+{"jr", 0, INSN_CLASS_ZCA, "d", MATCH_C_JR, MASK_C_JR, match_rd_nonzero, INSN_ALIAS|INSN_BRANCH },
{"jr", 0, INSN_CLASS_I, "s", MATCH_JALR, MASK_JALR|MASK_RD|MASK_IMM, match_opcode, INSN_ALIAS|INSN_BRANCH },
{"jr", 0, INSN_CLASS_I, "o(s)", MATCH_JALR, MASK_JALR|MASK_RD, match_opcode, INSN_ALIAS|INSN_BRANCH },
{"jr", 0, INSN_CLASS_I, "s,j", MATCH_JALR, MASK_JALR|MASK_RD, match_opcode, INSN_ALIAS|INSN_BRANCH },
-{"jalr", 0, INSN_CLASS_C, "d", MATCH_C_JALR, MASK_C_JALR, match_rd_nonzero, INSN_ALIAS|INSN_JSR },
+{"jalr", 0, INSN_CLASS_ZCA, "d", MATCH_C_JALR, MASK_C_JALR, match_rd_nonzero, INSN_ALIAS|INSN_JSR },
{"jalr", 0, INSN_CLASS_I, "s", MATCH_JALR|(X_RA << OP_SH_RD), MASK_JALR|MASK_RD|MASK_IMM, match_opcode, INSN_ALIAS|INSN_JSR },
{"jalr", 0, INSN_CLASS_I, "o(s)", MATCH_JALR|(X_RA << OP_SH_RD), MASK_JALR|MASK_RD, match_opcode, INSN_ALIAS|INSN_JSR },
{"jalr", 0, INSN_CLASS_I, "s,j", MATCH_JALR|(X_RA << OP_SH_RD), MASK_JALR|MASK_RD, match_opcode, INSN_ALIAS|INSN_JSR },
@@ -415,40 +415,40 @@ const struct riscv_opcode riscv_opcodes[] =
{"jalr", 0, INSN_CLASS_I, "d,o(s)", MATCH_JALR, MASK_JALR, match_opcode, INSN_JSR },
{"jalr", 0, INSN_CLASS_I, "d,s,1", MATCH_JALR, MASK_JALR|MASK_IMM, match_opcode, INSN_JSR },
{"jalr", 0, INSN_CLASS_I, "d,s,j", MATCH_JALR, MASK_JALR, match_opcode, INSN_JSR },
-{"j", 0, INSN_CLASS_C, "Ca", MATCH_C_J, MASK_C_J, match_opcode, INSN_ALIAS|INSN_BRANCH },
+{"j", 0, INSN_CLASS_ZCA, "Ca", MATCH_C_J, MASK_C_J, match_opcode, INSN_ALIAS|INSN_BRANCH },
{"j", 0, INSN_CLASS_I, "a", MATCH_JAL, MASK_JAL|MASK_RD, match_opcode, INSN_ALIAS|INSN_BRANCH },
-{"jal", 32, INSN_CLASS_C, "Ca", MATCH_C_JAL, MASK_C_JAL, match_opcode, INSN_ALIAS|INSN_JSR },
+{"jal", 32, INSN_CLASS_ZCA, "Ca", MATCH_C_JAL, MASK_C_JAL, match_opcode, INSN_ALIAS|INSN_JSR },
{"jal", 0, INSN_CLASS_I, "a", MATCH_JAL|(X_RA << OP_SH_RD), MASK_JAL|MASK_RD, match_opcode, INSN_ALIAS|INSN_JSR },
{"jal", 0, INSN_CLASS_I, "d,a", MATCH_JAL, MASK_JAL, match_opcode, INSN_JSR },
{"call", 0, INSN_CLASS_I, "d,c", (X_T1 << OP_SH_RS1), (int) M_CALL, NULL, INSN_MACRO },
{"call", 0, INSN_CLASS_I, "c", (X_RA << OP_SH_RS1)|(X_RA << OP_SH_RD), (int) M_CALL, NULL, INSN_MACRO },
{"tail", 0, INSN_CLASS_I, "c", (X_T1 << OP_SH_RS1), (int) M_CALL, NULL, INSN_MACRO },
{"jump", 0, INSN_CLASS_I, "c,s", 0, (int) M_CALL, match_rs1_nonzero, INSN_MACRO },
-{"nop", 0, INSN_CLASS_C, "", MATCH_C_ADDI, 0xffff, match_opcode, INSN_ALIAS },
+{"nop", 0, INSN_CLASS_ZCA, "", MATCH_C_ADDI, 0xffff, match_opcode, INSN_ALIAS },
{"nop", 0, INSN_CLASS_I, "", MATCH_ADDI, MASK_ADDI|MASK_RD|MASK_RS1|MASK_IMM, match_opcode, INSN_ALIAS },
-{"lui", 0, INSN_CLASS_C, "d,Cu", MATCH_C_LUI, MASK_C_LUI, match_c_lui, INSN_ALIAS },
+{"lui", 0, INSN_CLASS_ZCA, "d,Cu", MATCH_C_LUI, MASK_C_LUI, match_c_lui, INSN_ALIAS },
{"lui", 0, INSN_CLASS_I, "d,u", MATCH_LUI, MASK_LUI, match_opcode, 0 },
-{"li", 0, INSN_CLASS_C, "d,Cv", MATCH_C_LUI, MASK_C_LUI, match_c_lui, INSN_ALIAS },
-{"li", 0, INSN_CLASS_C, "d,Co", MATCH_C_LI, MASK_C_LI, match_rd_nonzero, INSN_ALIAS },
+{"li", 0, INSN_CLASS_ZCA, "d,Cv", MATCH_C_LUI, MASK_C_LUI, match_c_lui, INSN_ALIAS },
+{"li", 0, INSN_CLASS_ZCA, "d,Co", MATCH_C_LI, MASK_C_LI, match_rd_nonzero, INSN_ALIAS },
{"li", 0, INSN_CLASS_I, "d,j", MATCH_ADDI, MASK_ADDI|MASK_RS1, match_opcode, INSN_ALIAS }, /* addi */
{"li", 0, INSN_CLASS_I, "d,I", 0, (int) M_LI, NULL, INSN_MACRO },
-{"mv", 0, INSN_CLASS_C, "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS },
+{"mv", 0, INSN_CLASS_ZCA, "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS },
{"mv", 0, INSN_CLASS_I, "d,s", MATCH_ADDI, MASK_ADDI|MASK_IMM, match_opcode, INSN_ALIAS },
-{"move", 0, INSN_CLASS_C, "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS },
+{"move", 0, INSN_CLASS_ZCA, "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS },
{"move", 0, INSN_CLASS_I, "d,s", MATCH_ADDI, MASK_ADDI|MASK_IMM, match_opcode, INSN_ALIAS },
{"zext.b", 0, INSN_CLASS_ZCB, "Cs,Cw", MATCH_C_ZEXT_B, MASK_C_ZEXT_B, match_opcode, INSN_ALIAS },
{"zext.b", 0, INSN_CLASS_I, "d,s", MATCH_ANDI|ENCODE_ITYPE_IMM (255), MASK_ANDI | MASK_IMM, match_opcode, INSN_ALIAS },
{"andi", 0, INSN_CLASS_ZCB, "Cs,Cw,Wcf",MATCH_C_ZEXT_B, MASK_C_ZEXT_B, match_opcode, INSN_ALIAS },
-{"andi", 0, INSN_CLASS_C, "Cs,Cw,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS },
+{"andi", 0, INSN_CLASS_ZCA, "Cs,Cw,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS },
{"andi", 0, INSN_CLASS_I, "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, 0 },
-{"and", 0, INSN_CLASS_C, "Cs,Cw,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS },
-{"and", 0, INSN_CLASS_C, "Cs,Ct,Cw", MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS },
-{"and", 0, INSN_CLASS_C, "Cs,Cw,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS },
+{"and", 0, INSN_CLASS_ZCA, "Cs,Cw,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS },
+{"and", 0, INSN_CLASS_ZCA, "Cs,Ct,Cw", MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS },
+{"and", 0, INSN_CLASS_ZCA, "Cs,Cw,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS },
{"and", 0, INSN_CLASS_I, "d,s,t", MATCH_AND, MASK_AND, match_opcode, 0 },
{"and", 0, INSN_CLASS_I, "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, INSN_ALIAS },
-{"beqz", 0, INSN_CLASS_C, "Cs,Cp", MATCH_C_BEQZ, MASK_C_BEQZ, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
+{"beqz", 0, INSN_CLASS_ZCA, "Cs,Cp", MATCH_C_BEQZ, MASK_C_BEQZ, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
{"beqz", 0, INSN_CLASS_I, "s,p", MATCH_BEQ, MASK_BEQ|MASK_RS2, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
-{"beq", 0, INSN_CLASS_C, "Cs,Cz,Cp", MATCH_C_BEQZ, MASK_C_BEQZ, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
+{"beq", 0, INSN_CLASS_ZCA, "Cs,Cz,Cp", MATCH_C_BEQZ, MASK_C_BEQZ, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
{"beq", 0, INSN_CLASS_I, "s,t,p", MATCH_BEQ, MASK_BEQ, match_opcode, INSN_CONDBRANCH },
{"blez", 0, INSN_CLASS_I, "t,p", MATCH_BGE, MASK_BGE|MASK_RS1, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
{"bgez", 0, INSN_CLASS_I, "s,p", MATCH_BGE, MASK_BGE|MASK_RS2, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
@@ -462,23 +462,23 @@ const struct riscv_opcode riscv_opcodes[] =
{"bltu", 0, INSN_CLASS_I, "s,t,p", MATCH_BLTU, MASK_BLTU, match_opcode, INSN_CONDBRANCH },
{"bgt", 0, INSN_CLASS_I, "t,s,p", MATCH_BLT, MASK_BLT, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
{"bgtu", 0, INSN_CLASS_I, "t,s,p", MATCH_BLTU, MASK_BLTU, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
-{"bnez", 0, INSN_CLASS_C, "Cs,Cp", MATCH_C_BNEZ, MASK_C_BNEZ, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
+{"bnez", 0, INSN_CLASS_ZCA, "Cs,Cp", MATCH_C_BNEZ, MASK_C_BNEZ, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
{"bnez", 0, INSN_CLASS_I, "s,p", MATCH_BNE, MASK_BNE|MASK_RS2, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
-{"bne", 0, INSN_CLASS_C, "Cs,Cz,Cp", MATCH_C_BNEZ, MASK_C_BNEZ, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
+{"bne", 0, INSN_CLASS_ZCA, "Cs,Cz,Cp", MATCH_C_BNEZ, MASK_C_BNEZ, match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
{"bne", 0, INSN_CLASS_I, "s,t,p", MATCH_BNE, MASK_BNE, match_opcode, INSN_CONDBRANCH },
-{"addi", 0, INSN_CLASS_C, "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, INSN_ALIAS },
-{"addi", 0, INSN_CLASS_C, "d,CU,Cj", MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, INSN_ALIAS },
-{"addi", 0, INSN_CLASS_C, "d,CU,z", MATCH_C_NOP, MASK_C_ADDI|MASK_RVC_IMM, match_c_nop, INSN_ALIAS },
-{"addi", 0, INSN_CLASS_C, "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, INSN_ALIAS },
-{"addi", 0, INSN_CLASS_C, "d,Cz,Co", MATCH_C_LI, MASK_C_LI, match_rd_nonzero, INSN_ALIAS },
-{"addi", 0, INSN_CLASS_C, "d,CV,z", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS },
+{"addi", 0, INSN_CLASS_ZCA, "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, INSN_ALIAS },
+{"addi", 0, INSN_CLASS_ZCA, "d,CU,Cj", MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, INSN_ALIAS },
+{"addi", 0, INSN_CLASS_ZCA, "d,CU,z", MATCH_C_NOP, MASK_C_ADDI|MASK_RVC_IMM, match_c_nop, INSN_ALIAS },
+{"addi", 0, INSN_CLASS_ZCA, "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, INSN_ALIAS },
+{"addi", 0, INSN_CLASS_ZCA, "d,Cz,Co", MATCH_C_LI, MASK_C_LI, match_rd_nonzero, INSN_ALIAS },
+{"addi", 0, INSN_CLASS_ZCA, "d,CV,z", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS },
{"addi", 0, INSN_CLASS_I, "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, 0 },
-{"add", 0, INSN_CLASS_C, "d,CU,CV", MATCH_C_ADD, MASK_C_ADD, match_c_add, INSN_ALIAS },
-{"add", 0, INSN_CLASS_C, "d,CV,CU", MATCH_C_ADD, MASK_C_ADD, match_c_add, INSN_ALIAS },
-{"add", 0, INSN_CLASS_C, "d,CU,Co", MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, INSN_ALIAS },
-{"add", 0, INSN_CLASS_C, "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, INSN_ALIAS },
-{"add", 0, INSN_CLASS_C, "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, INSN_ALIAS },
-{"add", 0, INSN_CLASS_C, "d,Cz,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS },
+{"add", 0, INSN_CLASS_ZCA, "d,CU,CV", MATCH_C_ADD, MASK_C_ADD, match_c_add, INSN_ALIAS },
+{"add", 0, INSN_CLASS_ZCA, "d,CV,CU", MATCH_C_ADD, MASK_C_ADD, match_c_add, INSN_ALIAS },
+{"add", 0, INSN_CLASS_ZCA, "d,CU,Co", MATCH_C_ADDI, MASK_C_ADDI, match_rd_nonzero, INSN_ALIAS },
+{"add", 0, INSN_CLASS_ZCA, "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, INSN_ALIAS },
+{"add", 0, INSN_CLASS_ZCA, "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, INSN_ALIAS },
+{"add", 0, INSN_CLASS_ZCA, "d,Cz,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS },
{"add", 0, INSN_CLASS_I, "d,s,t", MATCH_ADD, MASK_ADD, match_opcode, 0 },
{"add", 0, INSN_CLASS_I, "d,s,t,1", MATCH_ADD, MASK_ADD, match_opcode, 0 },
{"add", 0, INSN_CLASS_I, "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, INSN_ALIAS },
@@ -488,22 +488,22 @@ const struct riscv_opcode riscv_opcodes[] =
{"la.tls.gd", 0, INSN_CLASS_I, "d,A", 0, (int) M_LA_TLS_GD, NULL, INSN_MACRO },
{"la.tls.ie", 0, INSN_CLASS_I, "d,A", 0, (int) M_LA_TLS_IE, match_rd_nonzero, INSN_MACRO },
{"neg", 0, INSN_CLASS_I, "d,t", MATCH_SUB, MASK_SUB|MASK_RS1, match_opcode, INSN_ALIAS }, /* sub 0 */
-{"slli", 0, INSN_CLASS_C, "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_slli_as_c_slli, INSN_ALIAS },
+{"slli", 0, INSN_CLASS_ZCA, "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_slli_as_c_slli, INSN_ALIAS },
{"slli", 0, INSN_CLASS_I, "d,s,>", MATCH_SLLI, MASK_SLLI, match_opcode, 0 },
-{"sll", 0, INSN_CLASS_C, "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_slli_as_c_slli, INSN_ALIAS },
+{"sll", 0, INSN_CLASS_ZCA, "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_slli_as_c_slli, INSN_ALIAS },
{"sll", 0, INSN_CLASS_I, "d,s,t", MATCH_SLL, MASK_SLL, match_opcode, 0 },
{"sll", 0, INSN_CLASS_I, "d,s,>", MATCH_SLLI, MASK_SLLI, match_opcode, INSN_ALIAS },
-{"srli", 0, INSN_CLASS_C, "Cs,Cw,C>", MATCH_C_SRLI, MASK_C_SRLI, match_srxi_as_c_srxi, INSN_ALIAS },
+{"srli", 0, INSN_CLASS_ZCA, "Cs,Cw,C>", MATCH_C_SRLI, MASK_C_SRLI, match_srxi_as_c_srxi, INSN_ALIAS },
{"srli", 0, INSN_CLASS_I, "d,s,>", MATCH_SRLI, MASK_SRLI, match_opcode, 0 },
-{"srl", 0, INSN_CLASS_C, "Cs,Cw,C>", MATCH_C_SRLI, MASK_C_SRLI, match_srxi_as_c_srxi, INSN_ALIAS },
+{"srl", 0, INSN_CLASS_ZCA, "Cs,Cw,C>", MATCH_C_SRLI, MASK_C_SRLI, match_srxi_as_c_srxi, INSN_ALIAS },
{"srl", 0, INSN_CLASS_I, "d,s,t", MATCH_SRL, MASK_SRL, match_opcode, 0 },
{"srl", 0, INSN_CLASS_I, "d,s,>", MATCH_SRLI, MASK_SRLI, match_opcode, INSN_ALIAS },
-{"srai", 0, INSN_CLASS_C, "Cs,Cw,C>", MATCH_C_SRAI, MASK_C_SRAI, match_srxi_as_c_srxi, INSN_ALIAS },
+{"srai", 0, INSN_CLASS_ZCA, "Cs,Cw,C>", MATCH_C_SRAI, MASK_C_SRAI, match_srxi_as_c_srxi, INSN_ALIAS },
{"srai", 0, INSN_CLASS_I, "d,s,>", MATCH_SRAI, MASK_SRAI, match_opcode, 0 },
-{"sra", 0, INSN_CLASS_C, "Cs,Cw,C>", MATCH_C_SRAI, MASK_C_SRAI, match_srxi_as_c_srxi, INSN_ALIAS },
+{"sra", 0, INSN_CLASS_ZCA, "Cs,Cw,C>", MATCH_C_SRAI, MASK_C_SRAI, match_srxi_as_c_srxi, INSN_ALIAS },
{"sra", 0, INSN_CLASS_I, "d,s,t", MATCH_SRA, MASK_SRA, match_opcode, 0 },
{"sra", 0, INSN_CLASS_I, "d,s,>", MATCH_SRAI, MASK_SRAI, match_opcode, INSN_ALIAS },
-{"sub", 0, INSN_CLASS_C, "Cs,Cw,Ct", MATCH_C_SUB, MASK_C_SUB, match_opcode, INSN_ALIAS },
+{"sub", 0, INSN_CLASS_ZCA, "Cs,Cw,Ct", MATCH_C_SUB, MASK_C_SUB, match_opcode, INSN_ALIAS },
{"sub", 0, INSN_CLASS_I, "d,s,t", MATCH_SUB, MASK_SUB, match_opcode, 0 },
{"lb", 0, INSN_CLASS_I, "d,o(s)", MATCH_LB, MASK_LB, match_opcode, INSN_DREF|INSN_1_BYTE },
{"lb", 0, INSN_CLASS_I, "d,A", 0, (int) M_Lx, match_rd_nonzero, INSN_MACRO },
@@ -516,16 +516,16 @@ const struct riscv_opcode riscv_opcodes[] =
{"lhu", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_LHU, MASK_C_LHU, match_opcode, INSN_ALIAS|INSN_DREF|INSN_2_BYTE },
{"lhu", 0, INSN_CLASS_I, "d,o(s)", MATCH_LHU, MASK_LHU, match_opcode, INSN_DREF|INSN_2_BYTE },
{"lhu", 0, INSN_CLASS_I, "d,A", 0, (int) M_Lx, match_rd_nonzero, INSN_MACRO },
-{"lw", 0, INSN_CLASS_C, "d,Cm(Cc)", MATCH_C_LWSP, MASK_C_LWSP, match_rd_nonzero, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
-{"lw", 0, INSN_CLASS_C, "Ct,Ck(Cs)", MATCH_C_LW, MASK_C_LW, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
+{"lw", 0, INSN_CLASS_ZCA, "d,Cm(Cc)", MATCH_C_LWSP, MASK_C_LWSP, match_rd_nonzero, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
+{"lw", 0, INSN_CLASS_ZCA, "Ct,Ck(Cs)", MATCH_C_LW, MASK_C_LW, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
{"lw", 0, INSN_CLASS_I, "d,o(s)", MATCH_LW, MASK_LW, match_opcode, INSN_DREF|INSN_4_BYTE },
{"lw", 0, INSN_CLASS_I, "d,A", 0, (int) M_Lx, match_rd_nonzero, INSN_MACRO },
{"not", 0, INSN_CLASS_ZCB, "Cs,Cw", MATCH_C_NOT, MASK_C_NOT, match_opcode, INSN_ALIAS },
{"not", 0, INSN_CLASS_I, "d,s", MATCH_XORI|MASK_IMM, MASK_XORI|MASK_IMM, match_opcode, INSN_ALIAS },
{"ori", 0, INSN_CLASS_I, "d,s,j", MATCH_ORI, MASK_ORI, match_opcode, 0 },
{"or", 0, INSN_CLASS_I, "d,s,j", MATCH_ORI, MASK_ORI, match_opcode, INSN_ALIAS },
-{"or", 0, INSN_CLASS_C, "Cs,Cw,Ct", MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS },
-{"or", 0, INSN_CLASS_C, "Cs,Ct,Cw", MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS },
+{"or", 0, INSN_CLASS_ZCA, "Cs,Cw,Ct", MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS },
+{"or", 0, INSN_CLASS_ZCA, "Cs,Ct,Cw", MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS },
{"or", 0, INSN_CLASS_I, "d,s,t", MATCH_OR, MASK_OR, match_opcode, 0 },
{"auipc", 0, INSN_CLASS_I, "d,u", MATCH_AUIPC, MASK_AUIPC, match_opcode, 0 },
{"seqz", 0, INSN_CLASS_I, "d,s", MATCH_SLTIU|ENCODE_ITYPE_IMM (1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS },
@@ -546,8 +546,8 @@ const struct riscv_opcode riscv_opcodes[] =
{"sh", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_SH, MASK_C_SH, match_opcode, INSN_DREF|INSN_2_BYTE|INSN_ALIAS },
{"sh", 0, INSN_CLASS_I, "t,q(s)", MATCH_SH, MASK_SH, match_opcode, INSN_DREF|INSN_2_BYTE },
{"sh", 0, INSN_CLASS_I, "t,A,s", 0, (int) M_Sx_FSx, match_rs1_nonzero, INSN_MACRO },
-{"sw", 0, INSN_CLASS_C, "CV,CM(Cc)", MATCH_C_SWSP, MASK_C_SWSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
-{"sw", 0, INSN_CLASS_C, "Ct,Ck(Cs)", MATCH_C_SW, MASK_C_SW, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
+{"sw", 0, INSN_CLASS_ZCA, "CV,CM(Cc)", MATCH_C_SWSP, MASK_C_SWSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
+{"sw", 0, INSN_CLASS_ZCA, "Ct,Ck(Cs)", MATCH_C_SW, MASK_C_SW, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
{"sw", 0, INSN_CLASS_I, "t,q(s)", MATCH_SW, MASK_SW, match_opcode, INSN_DREF|INSN_4_BYTE },
{"sw", 0, INSN_CLASS_I, "t,A,s", 0, (int) M_Sx_FSx, match_rs1_nonzero, INSN_MACRO },
{"fence", 0, INSN_CLASS_I, "", MATCH_FENCE|MASK_PRED|MASK_SUCC, MASK_FENCE|MASK_RD|MASK_RS1|MASK_IMM, match_opcode, INSN_ALIAS },
@@ -564,26 +564,26 @@ const struct riscv_opcode riscv_opcodes[] =
{"scall", 0, INSN_CLASS_I, "", MATCH_SCALL, MASK_SCALL, match_opcode, 0 },
{"xori", 0, INSN_CLASS_I, "d,s,j", MATCH_XORI, MASK_XORI, match_opcode, 0 },
{"xor", 0, INSN_CLASS_I, "d,s,j", MATCH_XORI, MASK_XORI, match_opcode, INSN_ALIAS },
-{"xor", 0, INSN_CLASS_C, "Cs,Cw,Ct", MATCH_C_XOR, MASK_C_XOR, match_opcode, INSN_ALIAS },
-{"xor", 0, INSN_CLASS_C, "Cs,Ct,Cw", MATCH_C_XOR, MASK_C_XOR, match_opcode, INSN_ALIAS },
+{"xor", 0, INSN_CLASS_ZCA, "Cs,Cw,Ct", MATCH_C_XOR, MASK_C_XOR, match_opcode, INSN_ALIAS },
+{"xor", 0, INSN_CLASS_ZCA, "Cs,Ct,Cw", MATCH_C_XOR, MASK_C_XOR, match_opcode, INSN_ALIAS },
{"xor", 0, INSN_CLASS_I, "d,s,t", MATCH_XOR, MASK_XOR, match_opcode, 0 },
{"lwu", 64, INSN_CLASS_I, "d,o(s)", MATCH_LWU, MASK_LWU, match_opcode, INSN_DREF|INSN_4_BYTE },
{"lwu", 64, INSN_CLASS_I, "d,A", 0, (int) M_Lx, match_rd_nonzero, INSN_MACRO },
-{"ld", 64, INSN_CLASS_C, "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
-{"ld", 64, INSN_CLASS_C, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
+{"ld", 64, INSN_CLASS_ZCA, "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
+{"ld", 64, INSN_CLASS_ZCA, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
{"ld", 64, INSN_CLASS_I, "d,o(s)", MATCH_LD, MASK_LD, match_opcode, INSN_DREF|INSN_8_BYTE },
{"ld", 64, INSN_CLASS_I, "d,A", 0, (int) M_Lx, match_rd_nonzero, INSN_MACRO },
-{"sd", 64, INSN_CLASS_C, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
-{"sd", 64, INSN_CLASS_C, "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
+{"sd", 64, INSN_CLASS_ZCA, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
+{"sd", 64, INSN_CLASS_ZCA, "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
{"sd", 64, INSN_CLASS_I, "t,q(s)", MATCH_SD, MASK_SD, match_opcode, INSN_DREF|INSN_8_BYTE },
{"sd", 64, INSN_CLASS_I, "t,A,s", 0, (int) M_Sx_FSx, match_rs1_nonzero, INSN_MACRO },
-{"sext.w", 64, INSN_CLASS_C, "d,CU", MATCH_C_ADDIW, MASK_C_ADDIW|MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS },
+{"sext.w", 64, INSN_CLASS_ZCA, "d,CU", MATCH_C_ADDIW, MASK_C_ADDIW|MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS },
{"sext.w", 64, INSN_CLASS_I, "d,s", MATCH_ADDIW, MASK_ADDIW|MASK_IMM, match_opcode, INSN_ALIAS },
-{"addiw", 64, INSN_CLASS_C, "d,CU,Co", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS },
+{"addiw", 64, INSN_CLASS_ZCA, "d,CU,Co", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS },
{"addiw", 64, INSN_CLASS_I, "d,s,j", MATCH_ADDIW, MASK_ADDIW, match_opcode, 0 },
-{"addw", 64, INSN_CLASS_C, "Cs,Cw,Ct", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, INSN_ALIAS },
-{"addw", 64, INSN_CLASS_C, "Cs,Ct,Cw", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, INSN_ALIAS },
-{"addw", 64, INSN_CLASS_C, "d,CU,Co", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS },
+{"addw", 64, INSN_CLASS_ZCA, "Cs,Cw,Ct", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, INSN_ALIAS },
+{"addw", 64, INSN_CLASS_ZCA, "Cs,Ct,Cw", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, INSN_ALIAS },
+{"addw", 64, INSN_CLASS_ZCA, "d,CU,Co", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS },
{"addw", 64, INSN_CLASS_I, "d,s,t", MATCH_ADDW, MASK_ADDW, match_opcode, 0 },
{"addw", 64, INSN_CLASS_I, "d,s,j", MATCH_ADDIW, MASK_ADDIW, match_opcode, INSN_ALIAS },
{"negw", 64, INSN_CLASS_I, "d,t", MATCH_SUBW, MASK_SUBW|MASK_RS1, match_opcode, INSN_ALIAS }, /* sub 0 */
@@ -596,7 +596,7 @@ const struct riscv_opcode riscv_opcodes[] =
{"sraiw", 64, INSN_CLASS_I, "d,s,<", MATCH_SRAIW, MASK_SRAIW, match_opcode, 0 },
{"sraw", 64, INSN_CLASS_I, "d,s,t", MATCH_SRAW, MASK_SRAW, match_opcode, 0 },
{"sraw", 64, INSN_CLASS_I, "d,s,<", MATCH_SRAIW, MASK_SRAIW, match_opcode, INSN_ALIAS },
-{"subw", 64, INSN_CLASS_C, "Cs,Cw,Ct", MATCH_C_SUBW, MASK_C_SUBW, match_opcode, INSN_ALIAS },
+{"subw", 64, INSN_CLASS_ZCA, "Cs,Cw,Ct", MATCH_C_SUBW, MASK_C_SUBW, match_opcode, INSN_ALIAS },
{"subw", 64, INSN_CLASS_I, "d,s,t", MATCH_SUBW, MASK_SUBW, match_opcode, 0 },
/* Atomic memory operation instruction subset. */
@@ -892,12 +892,12 @@ const struct riscv_opcode riscv_opcodes[] =
{"fsflags", 0, INSN_CLASS_F_INX, "d,s", MATCH_FSFLAGS, MASK_FSFLAGS, match_opcode, INSN_ALIAS },
{"fsflagsi", 0, INSN_CLASS_F_INX, "d,Z", MATCH_FSFLAGSI, MASK_FSFLAGSI, match_opcode, INSN_ALIAS },
{"fsflagsi", 0, INSN_CLASS_F_INX, "Z", MATCH_FSFLAGSI, MASK_FSFLAGSI|MASK_RD, match_opcode, INSN_ALIAS },
-{"flw", 32, INSN_CLASS_F_AND_C, "D,Cm(Cc)", MATCH_C_FLWSP, MASK_C_FLWSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
-{"flw", 32, INSN_CLASS_F_AND_C, "CD,Ck(Cs)", MATCH_C_FLW, MASK_C_FLW, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
+{"flw", 32, INSN_CLASS_ZCF, "D,Cm(Cc)", MATCH_C_FLWSP, MASK_C_FLWSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
+{"flw", 32, INSN_CLASS_ZCF, "CD,Ck(Cs)", MATCH_C_FLW, MASK_C_FLW, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
{"flw", 0, INSN_CLASS_F, "D,o(s)", MATCH_FLW, MASK_FLW, match_opcode, INSN_DREF|INSN_4_BYTE },
{"flw", 0, INSN_CLASS_F, "D,A,s", 0, (int) M_FLx, match_rs1_nonzero, INSN_MACRO },
-{"fsw", 32, INSN_CLASS_F_AND_C, "CT,CM(Cc)", MATCH_C_FSWSP, MASK_C_FSWSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
-{"fsw", 32, INSN_CLASS_F_AND_C, "CD,Ck(Cs)", MATCH_C_FSW, MASK_C_FSW, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
+{"fsw", 32, INSN_CLASS_ZCF, "CT,CM(Cc)", MATCH_C_FSWSP, MASK_C_FSWSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
+{"fsw", 32, INSN_CLASS_ZCF, "CD,Ck(Cs)", MATCH_C_FSW, MASK_C_FSW, match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
{"fsw", 0, INSN_CLASS_F, "T,q(s)", MATCH_FSW, MASK_FSW, match_opcode, INSN_DREF|INSN_4_BYTE },
{"fsw", 0, INSN_CLASS_F, "T,A,s", 0, (int) M_Sx_FSx, match_rs1_nonzero, INSN_MACRO },
{"fmv.x.w", 0, INSN_CLASS_F, "d,S", MATCH_FMV_X_S, MASK_FMV_X_S, match_opcode, 0 },
@@ -954,12 +954,12 @@ const struct riscv_opcode riscv_opcodes[] =
{"fcvt.s.lu", 64, INSN_CLASS_F_INX, "D,s,m", MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, 0 },
/* Double-precision floating-point instruction subset. */
-{"fld", 0, INSN_CLASS_D_AND_C, "D,Cn(Cc)", MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
-{"fld", 0, INSN_CLASS_D_AND_C, "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
+{"fld", 0, INSN_CLASS_ZCD, "D,Cn(Cc)", MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
+{"fld", 0, INSN_CLASS_ZCD, "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
{"fld", 0, INSN_CLASS_D, "D,o(s)", MATCH_FLD, MASK_FLD, match_opcode, INSN_DREF|INSN_8_BYTE },
{"fld", 0, INSN_CLASS_D, "D,A,s", 0, (int) M_FLx, match_rs1_nonzero, INSN_MACRO },
-{"fsd", 0, INSN_CLASS_D_AND_C, "CT,CN(Cc)", MATCH_C_FSDSP, MASK_C_FSDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
-{"fsd", 0, INSN_CLASS_D_AND_C, "CD,Cl(Cs)", MATCH_C_FSD, MASK_C_FSD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
+{"fsd", 0, INSN_CLASS_ZCD, "CT,CN(Cc)", MATCH_C_FSDSP, MASK_C_FSDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
+{"fsd", 0, INSN_CLASS_ZCD, "CD,Cl(Cs)", MATCH_C_FSD, MASK_C_FSD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
{"fsd", 0, INSN_CLASS_D, "T,q(s)", MATCH_FSD, MASK_FSD, match_opcode, INSN_DREF|INSN_8_BYTE },
{"fsd", 0, INSN_CLASS_D, "T,A,s", 0, (int) M_Sx_FSx, match_rs1_nonzero, INSN_MACRO },
{"fmv.d", 0, INSN_CLASS_D_INX, "D,U", MATCH_FSGNJ_D, MASK_FSGNJ_D, match_rs1_eq_rs2, INSN_ALIAS },
@@ -1073,53 +1073,53 @@ const struct riscv_opcode riscv_opcodes[] =
{"fcvt.q.lu", 64, INSN_CLASS_Q_INX, "D,s,m", MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU, match_opcode, 0 },
/* Compressed instructions. */
-{"c.unimp", 0, INSN_CLASS_C, "", 0, 0xffffU, match_opcode, 0 },
-{"c.ebreak", 0, INSN_CLASS_C, "", MATCH_C_EBREAK, MASK_C_EBREAK, match_opcode, 0 },
-{"c.jr", 0, INSN_CLASS_C, "d", MATCH_C_JR, MASK_C_JR, match_rd_nonzero, INSN_BRANCH },
-{"c.jalr", 0, INSN_CLASS_C, "d", MATCH_C_JALR, MASK_C_JALR, match_rd_nonzero, INSN_JSR },
-{"c.j", 0, INSN_CLASS_C, "Ca", MATCH_C_J, MASK_C_J, match_opcode, INSN_BRANCH },
-{"c.jal", 32, INSN_CLASS_C, "Ca", MATCH_C_JAL, MASK_C_JAL, match_opcode, INSN_JSR },
-{"c.beqz", 0, INSN_CLASS_C, "Cs,Cp", MATCH_C_BEQZ, MASK_C_BEQZ, match_opcode, INSN_CONDBRANCH },
-{"c.bnez", 0, INSN_CLASS_C, "Cs,Cp", MATCH_C_BNEZ, MASK_C_BNEZ, match_opcode, INSN_CONDBRANCH },
-{"c.lwsp", 0, INSN_CLASS_C, "d,Cm(Cc)", MATCH_C_LWSP, MASK_C_LWSP, match_rd_nonzero, 0 },
-{"c.lw", 0, INSN_CLASS_C, "Ct,Ck(Cs)", MATCH_C_LW, MASK_C_LW, match_opcode, INSN_DREF|INSN_4_BYTE },
-{"c.swsp", 0, INSN_CLASS_C, "CV,CM(Cc)", MATCH_C_SWSP, MASK_C_SWSP, match_opcode, INSN_DREF|INSN_4_BYTE },
-{"c.sw", 0, INSN_CLASS_C, "Ct,Ck(Cs)", MATCH_C_SW, MASK_C_SW, match_opcode, INSN_DREF|INSN_4_BYTE },
-{"c.nop", 0, INSN_CLASS_C, "", MATCH_C_ADDI, 0xffff, match_opcode, INSN_ALIAS },
-{"c.nop", 0, INSN_CLASS_C, "Cj", MATCH_C_ADDI, MASK_C_ADDI|MASK_RD, match_opcode, INSN_ALIAS },
-{"c.mv", 0, INSN_CLASS_C, "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add_with_hint, 0 },
-{"c.lui", 0, INSN_CLASS_C, "d,Cu", MATCH_C_LUI, MASK_C_LUI, match_c_lui_with_hint, 0 },
-{"c.li", 0, INSN_CLASS_C, "d,Co", MATCH_C_LI, MASK_C_LI, match_opcode, 0 },
-{"c.addi4spn", 0, INSN_CLASS_C, "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, 0 },
-{"c.addi16sp", 0, INSN_CLASS_C, "Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, 0 },
-{"c.addi", 0, INSN_CLASS_C, "d,Co", MATCH_C_ADDI, MASK_C_ADDI, match_opcode, 0 },
-{"c.add", 0, INSN_CLASS_C, "d,CV", MATCH_C_ADD, MASK_C_ADD, match_c_add_with_hint, 0 },
-{"c.sub", 0, INSN_CLASS_C, "Cs,Ct", MATCH_C_SUB, MASK_C_SUB, match_opcode, 0 },
-{"c.and", 0, INSN_CLASS_C, "Cs,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, 0 },
-{"c.or", 0, INSN_CLASS_C, "Cs,Ct", MATCH_C_OR, MASK_C_OR, match_opcode, 0 },
-{"c.xor", 0, INSN_CLASS_C, "Cs,Ct", MATCH_C_XOR, MASK_C_XOR, match_opcode, 0 },
-{"c.slli", 0, INSN_CLASS_C, "d,C>", MATCH_C_SLLI, MASK_C_SLLI, match_c_slli, 0 },
-{"c.srli", 0, INSN_CLASS_C, "Cs,C>", MATCH_C_SRLI, MASK_C_SRLI, match_c_slli, 0 },
-{"c.srai", 0, INSN_CLASS_C, "Cs,C>", MATCH_C_SRAI, MASK_C_SRAI, match_c_slli, 0 },
-{"c.slli64", 0, INSN_CLASS_C, "d", MATCH_C_SLLI64, MASK_C_SLLI64, match_c_slli64, 0 },
-{"c.srli64", 0, INSN_CLASS_C, "Cs", MATCH_C_SRLI64, MASK_C_SRLI64, match_c_slli64, 0 },
-{"c.srai64", 0, INSN_CLASS_C, "Cs", MATCH_C_SRAI64, MASK_C_SRAI64, match_c_slli64, 0 },
-{"c.andi", 0, INSN_CLASS_C, "Cs,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, 0 },
-{"c.addiw", 64, INSN_CLASS_C, "d,Co", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, 0 },
-{"c.addw", 64, INSN_CLASS_C, "Cs,Ct", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, 0 },
-{"c.subw", 64, INSN_CLASS_C, "Cs,Ct", MATCH_C_SUBW, MASK_C_SUBW, match_opcode, 0 },
-{"c.ldsp", 64, INSN_CLASS_C, "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, INSN_DREF|INSN_8_BYTE },
-{"c.ld", 64, INSN_CLASS_C, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, INSN_DREF|INSN_8_BYTE },
-{"c.sdsp", 64, INSN_CLASS_C, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, INSN_DREF|INSN_8_BYTE },
-{"c.sd", 64, INSN_CLASS_C, "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_opcode, INSN_DREF|INSN_8_BYTE },
-{"c.fldsp", 0, INSN_CLASS_D_AND_C, "D,Cn(Cc)", MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_DREF|INSN_8_BYTE },
-{"c.fld", 0, INSN_CLASS_D_AND_C, "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_DREF|INSN_8_BYTE },
-{"c.fsdsp", 0, INSN_CLASS_D_AND_C, "CT,CN(Cc)", MATCH_C_FSDSP, MASK_C_FSDSP, match_opcode, INSN_DREF|INSN_8_BYTE },
-{"c.fsd", 0, INSN_CLASS_D_AND_C, "CD,Cl(Cs)", MATCH_C_FSD, MASK_C_FSD, match_opcode, INSN_DREF|INSN_8_BYTE },
-{"c.flwsp", 32, INSN_CLASS_F_AND_C, "D,Cm(Cc)", MATCH_C_FLWSP, MASK_C_FLWSP, match_opcode, INSN_DREF|INSN_4_BYTE },
-{"c.flw", 32, INSN_CLASS_F_AND_C, "CD,Ck(Cs)", MATCH_C_FLW, MASK_C_FLW, match_opcode, INSN_DREF|INSN_4_BYTE },
-{"c.fswsp", 32, INSN_CLASS_F_AND_C, "CT,CM(Cc)", MATCH_C_FSWSP, MASK_C_FSWSP, match_opcode, INSN_DREF|INSN_4_BYTE },
-{"c.fsw", 32, INSN_CLASS_F_AND_C, "CD,Ck(Cs)", MATCH_C_FSW, MASK_C_FSW, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"c.unimp", 0, INSN_CLASS_ZCA, "", 0, 0xffffU, match_opcode, 0 },
+{"c.ebreak", 0, INSN_CLASS_ZCA, "", MATCH_C_EBREAK, MASK_C_EBREAK, match_opcode, 0 },
+{"c.jr", 0, INSN_CLASS_ZCA, "d", MATCH_C_JR, MASK_C_JR, match_rd_nonzero, INSN_BRANCH },
+{"c.jalr", 0, INSN_CLASS_ZCA, "d", MATCH_C_JALR, MASK_C_JALR, match_rd_nonzero, INSN_JSR },
+{"c.j", 0, INSN_CLASS_ZCA, "Ca", MATCH_C_J, MASK_C_J, match_opcode, INSN_BRANCH },
+{"c.jal", 32, INSN_CLASS_ZCA, "Ca", MATCH_C_JAL, MASK_C_JAL, match_opcode, INSN_JSR },
+{"c.beqz", 0, INSN_CLASS_ZCA, "Cs,Cp", MATCH_C_BEQZ, MASK_C_BEQZ, match_opcode, INSN_CONDBRANCH },
+{"c.bnez", 0, INSN_CLASS_ZCA, "Cs,Cp", MATCH_C_BNEZ, MASK_C_BNEZ, match_opcode, INSN_CONDBRANCH },
+{"c.lwsp", 0, INSN_CLASS_ZCA, "d,Cm(Cc)", MATCH_C_LWSP, MASK_C_LWSP, match_rd_nonzero, 0 },
+{"c.lw", 0, INSN_CLASS_ZCA, "Ct,Ck(Cs)", MATCH_C_LW, MASK_C_LW, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"c.swsp", 0, INSN_CLASS_ZCA, "CV,CM(Cc)", MATCH_C_SWSP, MASK_C_SWSP, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"c.sw", 0, INSN_CLASS_ZCA, "Ct,Ck(Cs)", MATCH_C_SW, MASK_C_SW, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"c.nop", 0, INSN_CLASS_ZCA, "", MATCH_C_ADDI, 0xffff, match_opcode, INSN_ALIAS },
+{"c.nop", 0, INSN_CLASS_ZCA, "Cj", MATCH_C_ADDI, MASK_C_ADDI|MASK_RD, match_opcode, INSN_ALIAS },
+{"c.mv", 0, INSN_CLASS_ZCA, "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add_with_hint, 0 },
+{"c.lui", 0, INSN_CLASS_ZCA, "d,Cu", MATCH_C_LUI, MASK_C_LUI, match_c_lui_with_hint, 0 },
+{"c.li", 0, INSN_CLASS_ZCA, "d,Co", MATCH_C_LI, MASK_C_LI, match_opcode, 0 },
+{"c.addi4spn", 0, INSN_CLASS_ZCA, "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, 0 },
+{"c.addi16sp", 0, INSN_CLASS_ZCA, "Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, 0 },
+{"c.addi", 0, INSN_CLASS_ZCA, "d,Co", MATCH_C_ADDI, MASK_C_ADDI, match_opcode, 0 },
+{"c.add", 0, INSN_CLASS_ZCA, "d,CV", MATCH_C_ADD, MASK_C_ADD, match_c_add_with_hint, 0 },
+{"c.sub", 0, INSN_CLASS_ZCA, "Cs,Ct", MATCH_C_SUB, MASK_C_SUB, match_opcode, 0 },
+{"c.and", 0, INSN_CLASS_ZCA, "Cs,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, 0 },
+{"c.or", 0, INSN_CLASS_ZCA, "Cs,Ct", MATCH_C_OR, MASK_C_OR, match_opcode, 0 },
+{"c.xor", 0, INSN_CLASS_ZCA, "Cs,Ct", MATCH_C_XOR, MASK_C_XOR, match_opcode, 0 },
+{"c.slli", 0, INSN_CLASS_ZCA, "d,C>", MATCH_C_SLLI, MASK_C_SLLI, match_c_slli, 0 },
+{"c.srli", 0, INSN_CLASS_ZCA, "Cs,C>", MATCH_C_SRLI, MASK_C_SRLI, match_c_slli, 0 },
+{"c.srai", 0, INSN_CLASS_ZCA, "Cs,C>", MATCH_C_SRAI, MASK_C_SRAI, match_c_slli, 0 },
+{"c.slli64", 0, INSN_CLASS_ZCA, "d", MATCH_C_SLLI64, MASK_C_SLLI64, match_c_slli64, 0 },
+{"c.srli64", 0, INSN_CLASS_ZCA, "Cs", MATCH_C_SRLI64, MASK_C_SRLI64, match_c_slli64, 0 },
+{"c.srai64", 0, INSN_CLASS_ZCA, "Cs", MATCH_C_SRAI64, MASK_C_SRAI64, match_c_slli64, 0 },
+{"c.andi", 0, INSN_CLASS_ZCA, "Cs,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, 0 },
+{"c.addiw", 64, INSN_CLASS_ZCA, "d,Co", MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, 0 },
+{"c.addw", 64, INSN_CLASS_ZCA, "Cs,Ct", MATCH_C_ADDW, MASK_C_ADDW, match_opcode, 0 },
+{"c.subw", 64, INSN_CLASS_ZCA, "Cs,Ct", MATCH_C_SUBW, MASK_C_SUBW, match_opcode, 0 },
+{"c.ldsp", 64, INSN_CLASS_ZCA, "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, INSN_DREF|INSN_8_BYTE },
+{"c.ld", 64, INSN_CLASS_ZCA, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, INSN_DREF|INSN_8_BYTE },
+{"c.sdsp", 64, INSN_CLASS_ZCA, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, INSN_DREF|INSN_8_BYTE },
+{"c.sd", 64, INSN_CLASS_ZCA, "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_opcode, INSN_DREF|INSN_8_BYTE },
+{"c.fldsp", 0, INSN_CLASS_ZCD, "D,Cn(Cc)", MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_DREF|INSN_8_BYTE },
+{"c.fld", 0, INSN_CLASS_ZCD, "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_DREF|INSN_8_BYTE },
+{"c.fsdsp", 0, INSN_CLASS_ZCD, "CT,CN(Cc)", MATCH_C_FSDSP, MASK_C_FSDSP, match_opcode, INSN_DREF|INSN_8_BYTE },
+{"c.fsd", 0, INSN_CLASS_ZCD, "CD,Cl(Cs)", MATCH_C_FSD, MASK_C_FSD, match_opcode, INSN_DREF|INSN_8_BYTE },
+{"c.flwsp", 32, INSN_CLASS_ZCF, "D,Cm(Cc)", MATCH_C_FLWSP, MASK_C_FLWSP, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"c.flw", 32, INSN_CLASS_ZCF, "CD,Ck(Cs)", MATCH_C_FLW, MASK_C_FLW, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"c.fswsp", 32, INSN_CLASS_ZCF, "CT,CM(Cc)", MATCH_C_FSWSP, MASK_C_FSWSP, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"c.fsw", 32, INSN_CLASS_ZCF, "CD,Ck(Cs)", MATCH_C_FSW, MASK_C_FSW, match_opcode, INSN_DREF|INSN_4_BYTE },
/* Zicbom and Zicboz instructions. */
{"cbo.clean", 0, INSN_CLASS_ZICBOM, "0(s)", MATCH_CBO_CLEAN, MASK_CBO_CLEAN, match_opcode, 0 },
@@ -3503,39 +3503,39 @@ const struct riscv_opcode riscv_insn_types[] =
{"j", 0, INSN_CLASS_I, "O4,d,a", 0, 0, NULL, 0 },
{"j", 0, INSN_CLASS_F, "O4,D,a", 0, 0, NULL, 0 },
-{"cr", 0, INSN_CLASS_C, "O2,CF4,d,CV", 0, 0, NULL, 0 },
-{"cr", 0, INSN_CLASS_F_AND_C, "O2,CF4,D,CV", 0, 0, NULL, 0 },
-{"cr", 0, INSN_CLASS_F_AND_C, "O2,CF4,d,CT", 0, 0, NULL, 0 },
-{"cr", 0, INSN_CLASS_F_AND_C, "O2,CF4,D,CT", 0, 0, NULL, 0 },
+{"cr", 0, INSN_CLASS_ZCA, "O2,CF4,d,CV", 0, 0, NULL, 0 },
+{"cr", 0, INSN_CLASS_ZCF, "O2,CF4,D,CV", 0, 0, NULL, 0 },
+{"cr", 0, INSN_CLASS_ZCF, "O2,CF4,d,CT", 0, 0, NULL, 0 },
+{"cr", 0, INSN_CLASS_ZCF, "O2,CF4,D,CT", 0, 0, NULL, 0 },
-{"ci", 0, INSN_CLASS_C, "O2,CF3,d,Co", 0, 0, NULL, 0 },
-{"ci", 0, INSN_CLASS_F_AND_C, "O2,CF3,D,Co", 0, 0, NULL, 0 },
+{"ci", 0, INSN_CLASS_ZCA, "O2,CF3,d,Co", 0, 0, NULL, 0 },
+{"ci", 0, INSN_CLASS_ZCF, "O2,CF3,D,Co", 0, 0, NULL, 0 },
-{"ciw", 0, INSN_CLASS_C, "O2,CF3,Ct,C8", 0, 0, NULL, 0 },
-{"ciw", 0, INSN_CLASS_F_AND_C, "O2,CF3,CD,C8", 0, 0, NULL, 0 },
+{"ciw", 0, INSN_CLASS_ZCA, "O2,CF3,Ct,C8", 0, 0, NULL, 0 },
+{"ciw", 0, INSN_CLASS_ZCF, "O2,CF3,CD,C8", 0, 0, NULL, 0 },
-{"css", 0, INSN_CLASS_C, "O2,CF3,CV,C6", 0, 0, NULL, 0 },
-{"css", 0, INSN_CLASS_F_AND_C, "O2,CF3,CT,C6", 0, 0, NULL, 0 },
+{"css", 0, INSN_CLASS_ZCA, "O2,CF3,CV,C6", 0, 0, NULL, 0 },
+{"css", 0, INSN_CLASS_ZCF, "O2,CF3,CT,C6", 0, 0, NULL, 0 },
-{"cl", 0, INSN_CLASS_C, "O2,CF3,Ct,C5(Cs)", 0, 0, NULL, 0 },
-{"cl", 0, INSN_CLASS_F_AND_C, "O2,CF3,CD,C5(Cs)", 0, 0, NULL, 0 },
-{"cl", 0, INSN_CLASS_F_AND_C, "O2,CF3,Ct,C5(CS)", 0, 0, NULL, 0 },
-{"cl", 0, INSN_CLASS_F_AND_C, "O2,CF3,CD,C5(CS)", 0, 0, NULL, 0 },
+{"cl", 0, INSN_CLASS_ZCA, "O2,CF3,Ct,C5(Cs)", 0, 0, NULL, 0 },
+{"cl", 0, INSN_CLASS_ZCF, "O2,CF3,CD,C5(Cs)", 0, 0, NULL, 0 },
+{"cl", 0, INSN_CLASS_ZCF, "O2,CF3,Ct,C5(CS)", 0, 0, NULL, 0 },
+{"cl", 0, INSN_CLASS_ZCF, "O2,CF3,CD,C5(CS)", 0, 0, NULL, 0 },
-{"cs", 0, INSN_CLASS_C, "O2,CF3,Ct,C5(Cs)", 0, 0, NULL, 0 },
-{"cs", 0, INSN_CLASS_F_AND_C, "O2,CF3,CD,C5(Cs)", 0, 0, NULL, 0 },
-{"cs", 0, INSN_CLASS_F_AND_C, "O2,CF3,Ct,C5(CS)", 0, 0, NULL, 0 },
-{"cs", 0, INSN_CLASS_F_AND_C, "O2,CF3,CD,C5(CS)", 0, 0, NULL, 0 },
+{"cs", 0, INSN_CLASS_ZCA, "O2,CF3,Ct,C5(Cs)", 0, 0, NULL, 0 },
+{"cs", 0, INSN_CLASS_ZCF, "O2,CF3,CD,C5(Cs)", 0, 0, NULL, 0 },
+{"cs", 0, INSN_CLASS_ZCF, "O2,CF3,Ct,C5(CS)", 0, 0, NULL, 0 },
+{"cs", 0, INSN_CLASS_ZCF, "O2,CF3,CD,C5(CS)", 0, 0, NULL, 0 },
-{"ca", 0, INSN_CLASS_C, "O2,CF6,CF2,Cs,Ct", 0, 0, NULL, 0 },
-{"ca", 0, INSN_CLASS_F_AND_C, "O2,CF6,CF2,CS,Ct", 0, 0, NULL, 0 },
-{"ca", 0, INSN_CLASS_F_AND_C, "O2,CF6,CF2,Cs,CD", 0, 0, NULL, 0 },
-{"ca", 0, INSN_CLASS_F_AND_C, "O2,CF6,CF2,CS,CD", 0, 0, NULL, 0 },
+{"ca", 0, INSN_CLASS_ZCA, "O2,CF6,CF2,Cs,Ct", 0, 0, NULL, 0 },
+{"ca", 0, INSN_CLASS_ZCF, "O2,CF6,CF2,CS,Ct", 0, 0, NULL, 0 },
+{"ca", 0, INSN_CLASS_ZCF, "O2,CF6,CF2,Cs,CD", 0, 0, NULL, 0 },
+{"ca", 0, INSN_CLASS_ZCF, "O2,CF6,CF2,CS,CD", 0, 0, NULL, 0 },
-{"cb", 0, INSN_CLASS_C, "O2,CF3,Cs,Cp", 0, 0, NULL, 0 },
-{"cb", 0, INSN_CLASS_F_AND_C, "O2,CF3,CS,Cp", 0, 0, NULL, 0 },
+{"cb", 0, INSN_CLASS_ZCA, "O2,CF3,Cs,Cp", 0, 0, NULL, 0 },
+{"cb", 0, INSN_CLASS_ZCF, "O2,CF3,CS,Cp", 0, 0, NULL, 0 },
-{"cj", 0, INSN_CLASS_C, "O2,CF3,Ca", 0, 0, NULL, 0 },
+{"cj", 0, INSN_CLASS_ZCA, "O2,CF3,Ca", 0, 0, NULL, 0 },
/* Terminate the list. */
{0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
--
2.39.3 (Apple Git-146)
More information about the Binutils
mailing list