aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/elf-sframe.c9
-rw-r--r--bfd/elfxx-riscv.c142
-rw-r--r--bfd/elfxx-riscv.h3
-rw-r--r--bfd/version.h2
-rw-r--r--gas/NEWS3
-rw-r--r--gas/config/tc-riscv.c3
-rw-r--r--gas/doc/c-riscv.texi36
-rw-r--r--gas/gen-sframe.c6
-rw-r--r--gas/testsuite/gas/riscv/align-1.s2
-rw-r--r--gas/testsuite/gas/riscv/attribute-10.d2
-rw-r--r--gas/testsuite/gas/riscv/attribute-17.d2
-rw-r--r--gas/testsuite/gas/riscv/attribute-19.d2
-rw-r--r--gas/testsuite/gas/riscv/attribute-20.d2
-rw-r--r--gas/testsuite/gas/riscv/attribute-rva23s.d2
-rw-r--r--gas/testsuite/gas/riscv/attribute-rvb23s.d2
-rw-r--r--gas/testsuite/gas/riscv/dis-addr-addiw.s2
-rw-r--r--gas/testsuite/gas/riscv/dis-addr-overflow.s4
-rw-r--r--gas/testsuite/gas/riscv/ext.s2
-rw-r--r--gas/testsuite/gas/riscv/imply.d22
-rw-r--r--gas/testsuite/gas/riscv/imply.s29
-rw-r--r--gas/testsuite/gas/riscv/mapping-symbols.d26
-rw-r--r--gas/testsuite/gas/riscv/mapping-x.s2
-rw-r--r--gas/testsuite/gas/riscv/mapping.s10
-rw-r--r--gas/testsuite/gas/riscv/march-imply-zce-f-32.d6
-rw-r--r--gas/testsuite/gas/riscv/march-imply-zce-f-64.d6
-rw-r--r--gas/testsuite/gas/riscv/march-imply-zce.d6
-rw-r--r--gas/testsuite/gas/riscv/march-ok-reorder.d2
-rw-r--r--gas/testsuite/gas/riscv/option-arch-attr.d2
-rw-r--r--gas/testsuite/gas/riscv/option-arch-dis.d6
-rw-r--r--gas/testsuite/gas/riscv/option-arch-fail.l7
-rw-r--r--gas/testsuite/gas/riscv/option-arch-fail.s1
-rw-r--r--gas/testsuite/gas/riscv/option-arch.s3
-rw-r--r--gas/testsuite/gas/riscv/option-norvc.d6
-rw-r--r--gas/testsuite/gas/riscv/shamt-32.s2
-rw-r--r--gas/testsuite/gas/riscv/shamt-64.s2
-rw-r--r--include/doubly-linked-list.h447
-rw-r--r--include/opcode/riscv.h8
-rw-r--r--include/sframe-api.h5
-rw-r--r--include/sframe-internal.h30
-rw-r--r--libiberty/Makefile.in1
-rw-r--r--libiberty/testsuite/Makefile.in12
-rw-r--r--libiberty/testsuite/test-doubly-linked-list.c269
-rw-r--r--opcodes/riscv-opc.c294
-rw-r--r--sim/riscv/sim-main.c2
44 files changed, 1102 insertions, 330 deletions
diff --git a/bfd/elf-sframe.c b/bfd/elf-sframe.c
index 24a3d35..d74235b 100644
--- a/bfd/elf-sframe.c
+++ b/bfd/elf-sframe.c
@@ -23,6 +23,7 @@
#include "libbfd.h"
#include "elf-bfd.h"
#include "sframe-api.h"
+#include "sframe-internal.h"
/* Return TRUE if the function has been marked for deletion during the linking
process. */
@@ -373,8 +374,8 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
uint8_t tflags = dctx_flags & ~SFRAME_F_FDE_SORTED;
/* ld always generates an output section with
SFRAME_F_FDE_FUNC_START_PCREL flag set. Later using
- SFRAME_F_LD_MUSTHAVE_FLAGS, it is enforced that the provided input
- sections also have this flag set. */
+ SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS, it is enforced that the provided
+ input sections also have this flag set. */
tflags |= SFRAME_F_FDE_FUNC_START_PCREL;
htab->sfe_info.sfe_ctx = sframe_encode (SFRAME_VERSION_2,
tflags, /* SFrame flags. */
@@ -430,8 +431,8 @@ _bfd_elf_merge_section_sframe (bfd *abfd,
related flags set. The implementation does not support updating these
data encodings on the fly; confirm by checking the ectx_flags. */
ectx_flags = sframe_encoder_get_flags (sfe_ctx);
- if ((dctx_flags & ectx_flags & SFRAME_F_LD_MUSTHAVE_FLAGS)
- != SFRAME_F_LD_MUSTHAVE_FLAGS)
+ if ((dctx_flags & ectx_flags & SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS)
+ != SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS)
{
_bfd_error_handler
(_("SFrame sections with unexpected data encoding prevent"
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 43d3c0d..1200032 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1178,9 +1178,20 @@ static bool
check_implicit_for_zcf (riscv_parse_subset_t *rps,
const riscv_subset_t *subset ATTRIBUTE_UNUSED)
{
- riscv_subset_t *tmp = NULL;
- return *rps->xlen == 32
- && riscv_lookup_subset (rps->subset_list, "f", &tmp);
+ return (rps != NULL
+ && rps->xlen != NULL
+ && *rps->xlen == 32
+ && riscv_subset_supports (rps, "f"));
+}
+
+/* Add the implicit only when 'd' extension is also available. */
+
+static bool
+check_implicit_for_zcd (riscv_parse_subset_t *rps,
+ const riscv_subset_t *subset ATTRIBUTE_UNUSED)
+{
+ return (rps != NULL
+ && riscv_subset_supports (rps, "d"));
}
/* Record all implicit information for the subsets. */
@@ -1237,15 +1248,6 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
{"zvl128b", "+zvl64b", check_implicit_always},
{"zvl64b", "+zvl32b", check_implicit_always},
- {"zce", "+zca,+zcb,+zcmp,+zcmt", check_implicit_always},
- {"zce", "+zcf", check_implicit_for_zcf},
- {"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},
- {"zcmt", "+zca,+zicsr", check_implicit_always},
-
{"zicfilp", "+zicsr", check_implicit_always},
{"zicfiss", "+zimop,+zicsr", check_implicit_always},
{"zclsd", "+zca,+zilsd", check_implicit_always},
@@ -1262,6 +1264,9 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
{"zhinx", "+zhinxmin", check_implicit_always},
{"zhinxmin", "+zfinx", check_implicit_always},
+ {"zcd", "+d,+zca", check_implicit_always},
+ {"zcf", "+f,+zca", check_implicit_always},
+
{"q", "+d", check_implicit_always},
{"zqinx", "+zdinx", check_implicit_always},
@@ -1275,6 +1280,16 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
{"zfinx", "+zicsr", check_implicit_always},
{"f", "+zicsr", check_implicit_always},
+ {"zce", "+zcb,+zcmp,+zcmt", check_implicit_always},
+ {"zce", "+zcf", check_implicit_for_zcf},
+ {"zcb", "+zca", check_implicit_always},
+ {"zcmp", "+zca", check_implicit_always},
+ {"zcmop", "+zca", check_implicit_always},
+ {"zcmt", "+zca,+zicsr", check_implicit_always},
+ {"c", "+zcf", check_implicit_for_zcf},
+ {"c", "+zcd", check_implicit_for_zcd},
+ {"c", "+zca", check_implicit_always},
+
{"b", "+zba,+zbb,+zbs", check_implicit_always},
{"zk", "+zkn,+zkr,+zkt", check_implicit_always},
@@ -2208,7 +2223,7 @@ riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
&& riscv_subset_supports (rps, "zcd"))
{
rps->error_handler
- (_("zcmp' is incompatible with `d/zcd' extension"));
+ (_("zcmp' is incompatible with `d' and `c', or `zcd' extension"));
no_conflict = false;
}
if (riscv_lookup_subset (rps->subset_list, "zcf", &subset)
@@ -2602,7 +2617,7 @@ riscv_remove_subset (riscv_subset_list_t *subset_list,
called from riscv_update_subset./
The IMPLICIT_EXTS, +extension[version] [,...,+extension_n[version_n]]
- -extension [,...,-extension_n],
+ (Deprecated) -extension [,...,-extension_n],
full ISA. */
static bool
@@ -2694,16 +2709,26 @@ riscv_update_subset1 (riscv_parse_subset_t *rps,
return false;
}
- if (explicit_subset == NULL
- && (strcmp (subset, "i") == 0
- || strcmp (subset, "e") == 0
- || strcmp (subset, "g") == 0))
+ if (explicit_subset == NULL)
{
- rps->error_handler
- (_("%scannot + or - base extension `%s' in %s `%s'"),
- errmsg_internal, subset, errmsg_caller, implicit_exts);
- free (subset);
- return false;
+ if (removed)
+ {
+ rps->error_handler
+ (_("%sdeprecated - extension `%s' in %s `%s'"),
+ errmsg_internal, subset, errmsg_caller, implicit_exts);
+ free (subset);
+ return false;
+ }
+ else if (strcmp (subset, "i") == 0
+ || strcmp (subset, "e") == 0
+ || strcmp (subset, "g") == 0)
+ {
+ rps->error_handler
+ (_("%scannot + base extension `%s' in %s `%s'"),
+ errmsg_internal, subset, errmsg_caller, implicit_exts);
+ free (subset);
+ return false;
+ }
}
if (removed)
@@ -2729,8 +2754,8 @@ riscv_update_subset1 (riscv_parse_subset_t *rps,
return no_conflict;
}
-/* Add/Remove an extension to/from the subset list. This is used for
- the .option rvc or norvc, and .option arch directives. */
+/* Add an extension to/from the subset list. This is used for the .option rvc
+ and .option arch directives. */
bool
riscv_update_subset (riscv_parse_subset_t *rps,
@@ -2739,6 +2764,16 @@ riscv_update_subset (riscv_parse_subset_t *rps,
return riscv_update_subset1 (rps, NULL, str);
}
+/* Called from .option norvc directives. */
+
+bool
+riscv_update_subset_norvc (riscv_parse_subset_t *rps)
+{
+ return riscv_update_subset1 (rps, rps->subset_list->head,
+ "-c,-zca,-zcd,-zcf,-zcb,-zce,-zcmp,-zcmt,"
+ "-zcmop,-zclsd");
+}
+
/* Check if the FEATURE subset is supported or not in the subset list.
Return true if it is supported; Otherwise, return false. */
@@ -2775,10 +2810,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:
- return (riscv_subset_supports (rps, "zihintntl")
- && (riscv_subset_supports (rps, "c")
- || riscv_subset_supports (rps, "zca")));
+ case INSN_CLASS_ZIHINTNTL_AND_ZCA:
+ return riscv_subset_supports (rps, "zihintntl")
+ && riscv_subset_supports (rps, "zca");
case INSN_CLASS_ZIHINTPAUSE:
return riscv_subset_supports (rps, "zihintpause");
case INSN_CLASS_ZIMOP:
@@ -2813,17 +2847,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"));
@@ -3070,11 +3099,10 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return "zicfilp";
case INSN_CLASS_ZIHINTNTL:
return "zihintntl";
- case INSN_CLASS_ZIHINTNTL_AND_C:
+ case INSN_CLASS_ZIHINTNTL_AND_ZCA:
if (!riscv_subset_supports (rps, "zihintntl"))
{
- if (!riscv_subset_supports (rps, "c")
- && !riscv_subset_supports (rps, "zca"))
+ if (!riscv_subset_supports (rps, "zca"))
return _("zihintntl' and `c', or `zihintntl' and `zca");
else
return "zihintntl";
@@ -3105,30 +3133,12 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return "d";
case INSN_CLASS_Q:
return "q";
- case INSN_CLASS_C:
+ case INSN_CLASS_ZCA:
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_ZCF:
+ return _("f' and `c', or `zcf");
+ case INSN_CLASS_ZCD:
+ return _("d' and `c', or `zcd");
case INSN_CLASS_F_INX:
return _("f' or `zfinx");
case INSN_CLASS_D_INX:
diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
index db494d0..fbbefb5 100644
--- a/bfd/elfxx-riscv.h
+++ b/bfd/elfxx-riscv.h
@@ -119,6 +119,9 @@ extern bool
riscv_update_subset (riscv_parse_subset_t *, const char *);
extern bool
+riscv_update_subset_norvc (riscv_parse_subset_t *);
+
+extern bool
riscv_subset_supports (riscv_parse_subset_t *, const char *);
extern bool
diff --git a/bfd/version.h b/bfd/version.h
index 4371993..7739244 100644
--- a/bfd/version.h
+++ b/bfd/version.h
@@ -16,7 +16,7 @@
In releases, the date is not included in either version strings or
sonames. */
-#define BFD_VERSION_DATE 20250709
+#define BFD_VERSION_DATE 20250710
#define BFD_VERSION @bfd_version@
#define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@
#define REPORT_BUGS_TO @report_bugs_to@
diff --git a/gas/NEWS b/gas/NEWS
index 66a9a7a..cbca8fe 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -14,6 +14,9 @@
* Support for x86 AVX10.2 256 bit rounding has been dropped, as all the
hardware would directly support 512 bit vecotr width.
+* For RISC-V, the ".option arch, -ext" format is deprecated due to its
+ controversial use.
+
* For RISC-V, stop generating mapping symbols $x and replace with $x<isa>. The
$x was defined to have the same ISA as previous $x<isa>, but now is defined
to have the same ISA as elf architecture attribute. Once used .option arch
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index f0b119f..8a33568 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -5073,8 +5073,7 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
}
else if (strcmp (name, "norvc") == 0)
{
- riscv_update_subset (&riscv_rps_as, "-c,-zca,-zcd,-zcf,-zcb,-zce,-zcmp,"
- "-zcmt,-zcmop,-zclsd");
+ riscv_update_subset_norvc (&riscv_rps_as);
riscv_arch_str (xlen, riscv_rps_as.subset_list, true/* update */);
riscv_set_rvc (false);
}
diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi
index a4c819e..ea4be32 100644
--- a/gas/doc/c-riscv.texi
+++ b/gas/doc/c-riscv.texi
@@ -181,12 +181,14 @@ instead of just
It's not expected that options are changed in this manner during regular use,
but there are a handful of esoteric cases like the one above where users need
to disable particular features of the assembler for particular code sequences.
-However, it's also useful to enable/disable the extensions for some specific
-code regions by @samp{.option arch, +-}. This is very common in the ifunc
-libraries. We can support functions which are implemented by different
-extensions in the same library, but these should not affect any file-level
-settings, like the elf architecture attribute. The complete list of option
-arguments is shown below:
+However, it's also useful to enable and reset the extensions for some specific
+code regions by @samp{.option arch, +ext} and @samp{.option arch, ISA}. Or
+use @samp{.option push} and @samp{.option pop} at the beginning and end of the
+code, so that we can indirectly turn on and off extensions in this range. This
+is very common in the ifunc libraries. We can support functions which are
+implemented by different extensions in the same library, but these should not
+affect any file-level settings, like the elf architecture attribute. The
+complete list of option arguments is shown below:
@table @code
@item push
@@ -197,9 +199,11 @@ command-line options are respected for the bulk of the file being assembled.
@item rvc
@itemx norvc
-Enables or disables the generation of compressed instructions. Instructions
-are opportunistically compressed by the RISC-V assembler when possible, but
-sometimes this behavior is not desirable, especially when handling alignments.
+Enable the generation of base compressed instructions (C extension), or
+disable the generation of all compressed instructions (C and all Zc*
+extensions). Instructions are opportunistically compressed by the RISC-V
+assembler when possible, but sometimes this behavior is not desirable,
+especially when handling alignments.
@item pic
@itemx nopic
@@ -217,17 +221,11 @@ desirable.
Enables or disables the CSR checking.
@item arch, @var{+extension[version]} [,...,@var{+extension_n[version_n]}]
-@itemx arch, @var{-extension} [,...,@var{-extension_n}]
@itemx arch, @var{ISA}
-Enables or disables the extensions for specific code region. For example,
-@samp{.option arch, +m2p0} means add m extension with version 2.0, and
-@samp{.option arch, -f, -d} means remove extensions, f and d, from the
-architecture string. Note that, @samp{.option arch, +c, -c} have the same
-behavior as @samp{.option rvc, norvc}. However, they are also undesirable
-sometimes. Besides, @samp{.option arch, -i} is illegal, since we cannot
-remove the base i extension anytime. If you want to reset the whole ISA
-string, you can also use @samp{.option arch, rv32imac} to overwrite the
-previous settings.
+Enable or reset the extensions for specific code region. For example,
+@samp{.option arch, +m2p0} means add m extension with version 2.0.
+@samp{.option arch, rv32imac} means reset and overwrite the previous settings
+by rv32imac.
@end table
@cindex INSN directives
diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c
index 7e29f84..3cba508 100644
--- a/gas/gen-sframe.c
+++ b/gas/gen-sframe.c
@@ -21,7 +21,7 @@
#include "as.h"
#include "subsegs.h"
#include "sframe.h"
-#include "sframe-api.h"
+#include "sframe-internal.h"
#include "gen-sframe.h"
#include "dw2gencfi.h"
@@ -685,8 +685,8 @@ output_sframe_internal (void)
out_one (SFRAME_VERSION);
/* gas must ensure emitted SFrame sections have at least the required flags
set. */
- gas_assert ((sframe_flags & SFRAME_F_LD_MUSTHAVE_FLAGS)
- == SFRAME_F_LD_MUSTHAVE_FLAGS);
+ gas_assert ((sframe_flags & SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS)
+ == SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS);
out_one (sframe_flags);
/* abi/arch. */
#ifdef sframe_get_abi_arch
diff --git a/gas/testsuite/gas/riscv/align-1.s b/gas/testsuite/gas/riscv/align-1.s
index ec28556..ee6a94d 100644
--- a/gas/testsuite/gas/riscv/align-1.s
+++ b/gas/testsuite/gas/riscv/align-1.s
@@ -1,3 +1,3 @@
- .option arch, -c
+ .option norvc
.align 2
.align 1
diff --git a/gas/testsuite/gas/riscv/attribute-10.d b/gas/testsuite/gas/riscv/attribute-10.d
index 04c322a..cb3ae5a 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/attribute-17.d b/gas/testsuite/gas/riscv/attribute-17.d
index 8e87e8e..f431b04 100644
--- a/gas/testsuite/gas/riscv/attribute-17.d
+++ b/gas/testsuite/gas/riscv/attribute-17.d
@@ -3,4 +3,4 @@
#source: empty.s
Attribute Section: riscv
File Attributes
- Tag_RISCV_arch: "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_ziccamoa1p0_ziccif1p0_zicclsm1p0_ziccrse1p0_zicntr2p0_zicsr2p0_zmmul1p0_za128rs1p0_zaamo1p0_zalrsc1p0"
+ Tag_RISCV_arch: "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_ziccamoa1p0_ziccif1p0_zicclsm1p0_ziccrse1p0_zicntr2p0_zicsr2p0_zmmul1p0_za128rs1p0_zaamo1p0_zalrsc1p0_zca1p0_zcd1p0"
diff --git a/gas/testsuite/gas/riscv/attribute-19.d b/gas/testsuite/gas/riscv/attribute-19.d
index d73e3f0..b9b5a40 100644
--- a/gas/testsuite/gas/riscv/attribute-19.d
+++ b/gas/testsuite/gas/riscv/attribute-19.d
@@ -3,4 +3,4 @@
#source: empty.s
Attribute Section: riscv
File Attributes
- Tag_RISCV_arch: "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_v1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0_ziccrse1p0_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0_zmmul1p0_za64rs1p0_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcmop1p0_zba1p0_zbb1p0_zbs1p0_zkt1p0_zvbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvfhmin1p0_zvkb1p0_zvkt1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_supm1p0"
+ Tag_RISCV_arch: "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_v1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0_ziccrse1p0_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0_zmmul1p0_za64rs1p0_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcd1p0_zcmop1p0_zba1p0_zbb1p0_zbs1p0_zkt1p0_zvbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvfhmin1p0_zvkb1p0_zvkt1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_supm1p0"
diff --git a/gas/testsuite/gas/riscv/attribute-20.d b/gas/testsuite/gas/riscv/attribute-20.d
index 22bcc13..7fbfda0 100644
--- a/gas/testsuite/gas/riscv/attribute-20.d
+++ b/gas/testsuite/gas/riscv/attribute-20.d
@@ -3,4 +3,4 @@
#source: empty.s
Attribute Section: riscv
File Attributes
- Tag_RISCV_arch: "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0_ziccrse1p0_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0_zmmul1p0_za64rs1p0_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcmop1p0_zba1p0_zbb1p0_zbs1p0_zkt1p0_supm1p0"
+ Tag_RISCV_arch: "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0_ziccrse1p0_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0_zmmul1p0_za64rs1p0_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcd1p0_zcmop1p0_zba1p0_zbb1p0_zbs1p0_zkt1p0_supm1p0"
diff --git a/gas/testsuite/gas/riscv/attribute-rva23s.d b/gas/testsuite/gas/riscv/attribute-rva23s.d
index 54e79aa..b38b7b9 100644
--- a/gas/testsuite/gas/riscv/attribute-rva23s.d
+++ b/gas/testsuite/gas/riscv/attribute-rva23s.d
@@ -3,4 +3,4 @@
#source: empty.s
Attribute Section: riscv
File Attributes
- Tag_RISCV_arch: "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_v1p0_h1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0_ziccrse1p0_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0_zmmul1p0_za64rs1p0_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcmop1p0_zba1p0_zbb1p0_zbs1p0_zkt1p0_zvbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvfhmin1p0_zvkb1p0_zvkt1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_sha1p0_shcounterenw1p0_shgatpa1p0_shtvala1p0_shvsatpa1p0_shvstvala1p0_shvstvecd1p0_ssccptr1p0_sscofpmf1p0_sscounterenw1p0_ssnpm1p0_ssstateen1p0_sstc1p0_sstvala1p0_sstvecd1p0_ssu64xl1p0_supm1p0_svade1p0_svbare1p0_svinval1p0_svnapot1p0_svpbmt1p0"
+ Tag_RISCV_arch: "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_v1p0_h1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0_ziccrse1p0_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0_zmmul1p0_za64rs1p0_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcd1p0_zcmop1p0_zba1p0_zbb1p0_zbs1p0_zkt1p0_zvbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvfhmin1p0_zvkb1p0_zvkt1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_sha1p0_shcounterenw1p0_shgatpa1p0_shtvala1p0_shvsatpa1p0_shvstvala1p0_shvstvecd1p0_ssccptr1p0_sscofpmf1p0_sscounterenw1p0_ssnpm1p0_ssstateen1p0_sstc1p0_sstvala1p0_sstvecd1p0_ssu64xl1p0_supm1p0_svade1p0_svbare1p0_svinval1p0_svnapot1p0_svpbmt1p0"
diff --git a/gas/testsuite/gas/riscv/attribute-rvb23s.d b/gas/testsuite/gas/riscv/attribute-rvb23s.d
index 5cee65a..87e243c 100644
--- a/gas/testsuite/gas/riscv/attribute-rvb23s.d
+++ b/gas/testsuite/gas/riscv/attribute-rvb23s.d
@@ -3,4 +3,4 @@
#source: empty.s
Attribute Section: riscv
File Attributes
- Tag_RISCV_arch: "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0_ziccrse1p0_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0_zmmul1p0_za64rs1p0_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcmop1p0_zba1p0_zbb1p0_zbs1p0_zkt1p0_zvbb1p0_zve32f1p0_zve32x1p0_zvfhmin1p0_zvkb1p0_zvkt1p0_zvl32b1p0_ssccptr1p0_sscofpmf1p0_sscounterenw1p0_sstc1p0_sstvala1p0_sstvecd1p0_ssu64xl1p0_supm1p0_svade1p0_svbare1p0_svinval1p0_svnapot1p0_svpbmt1p0"
+ Tag_RISCV_arch: "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_b1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0_ziccrse1p0_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0_zmmul1p0_za64rs1p0_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcd1p0_zcmop1p0_zba1p0_zbb1p0_zbs1p0_zkt1p0_zvbb1p0_zve32f1p0_zve32x1p0_zvfhmin1p0_zvkb1p0_zvkt1p0_zvl32b1p0_ssccptr1p0_sscofpmf1p0_sscounterenw1p0_sstc1p0_sstvala1p0_sstvecd1p0_ssu64xl1p0_supm1p0_svade1p0_svbare1p0_svinval1p0_svnapot1p0_svpbmt1p0"
diff --git a/gas/testsuite/gas/riscv/dis-addr-addiw.s b/gas/testsuite/gas/riscv/dis-addr-addiw.s
index 7c878f8..38dc1c9 100644
--- a/gas/testsuite/gas/riscv/dis-addr-addiw.s
+++ b/gas/testsuite/gas/riscv/dis-addr-addiw.s
@@ -11,7 +11,7 @@
.global _start
_start:
.option push
- .option arch, -c
+ .option norvc
# _start + 0x00
auipc t0, 0
addiw t1, t0, 0x18
diff --git a/gas/testsuite/gas/riscv/dis-addr-overflow.s b/gas/testsuite/gas/riscv/dis-addr-overflow.s
index 77ca39c..db48ae3 100644
--- a/gas/testsuite/gas/riscv/dis-addr-overflow.s
+++ b/gas/testsuite/gas/riscv/dis-addr-overflow.s
@@ -24,7 +24,7 @@ topbase = 0
target:
.option push
- .option arch, -c
+ .option norvc
## Use hi_addr
# Load
lui t0, 0xfffff
@@ -50,7 +50,7 @@ target:
c.addi t6, -20
.ifdef rv64
.option push
- .option arch, -c
+ .option norvc
# ADDIW (not compressed)
lui s6, 0xffff8
addiw s7, s6, -24
diff --git a/gas/testsuite/gas/riscv/ext.s b/gas/testsuite/gas/riscv/ext.s
index 0268dca..b6ccce0 100644
--- a/gas/testsuite/gas/riscv/ext.s
+++ b/gas/testsuite/gas/riscv/ext.s
@@ -1,5 +1,5 @@
target:
- .option arch, -c
+ .option norvc
zext.b a0, a0
zext.h a0, a0
sext.b a0, a0
diff --git a/gas/testsuite/gas/riscv/imply.d b/gas/testsuite/gas/riscv/imply.d
index b68da92..c60711c 100644
--- a/gas/testsuite/gas/riscv/imply.d
+++ b/gas/testsuite/gas/riscv/imply.d
@@ -45,12 +45,6 @@ SYMBOL TABLE:
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl64b1p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zicsr2p0_zve32x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zicsr2p0_zve32x1p0_zvl32b1p0_zvl64b1p0
-[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zca1p0_zcb1p0
-[0-9a-f]+ l .text 0+000 \$xrv32i2p1_f2p2_d2p2_zicsr2p0_zca1p0_zcd1p0
-[0-9a-f]+ l .text 0+000 \$xrv32i2p1_f2p2_zicsr2p0_zca1p0_zcf1p0
-[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zca1p0_zcmp1p0
-[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zca1p0_zcmop1p0
-[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zicsr2p0_zca1p0_zcmt1p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zicfilp1p0_zicsr2p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zicfiss1p0_zicsr2p0_zimop1p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_h1p0_zicsr2p0_sha1p0_shcounterenw1p0_shgatpa1p0_shtvala1p0_shvsatpa1p0_shvstvala1p0_shvstvecd1p0_ssstateen1p0
@@ -63,6 +57,8 @@ SYMBOL TABLE:
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_h1p0_zicsr2p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zicsr2p0_zfinx1p0_zhinx1p0_zhinxmin1p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zicsr2p0_zfinx1p0_zhinxmin1p0
+[0-9a-f]+ l .text 0+000 \$xrv32i2p1_f2p2_d2p2_zicsr2p0_zca1p0_zcd1p0
+[0-9a-f]+ l .text 0+000 \$xrv32i2p1_f2p2_zicsr2p0_zca1p0_zcf1p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_f2p2_d2p2_q2p2_zicsr2p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zicsr2p0_zfinx1p0_zdinx1p0_zqinx1p0
[0-9a-f]+ l .text 0+000 \$xrv32i2p1_f2p2_d2p2_zicsr2p0
@@ -73,6 +69,20 @@ 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_f2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcf1p0_zcmp1p0_zcmt1p0
+[0-9a-f]+ l .text 0+000 \$xrv64i2p1_f2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0
+[0-9a-f]+ l .text 0+000 \$xrv32i2p1_f2p2_d2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcf1p0_zcmp1p0_zcmt1p0
+[0-9a-f]+ l .text 0+000 \$xrv64i2p1_f2p2_d2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0
+[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0
+[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zca1p0_zcb1p0
+[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zca1p0_zcmp1p0
+[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zca1p0_zcmop1p0
+[0-9a-f]+ l .text 0+000 \$xrv32i2p1_zicsr2p0_zca1p0_zcmt1p0
+[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_c2p0_zca1p0
[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 35c68d3..74f2892 100644
--- a/gas/testsuite/gas/riscv/imply.s
+++ b/gas/testsuite/gas/riscv/imply.s
@@ -1,6 +1,6 @@
-.macro imply string base=i
+.macro imply string base=i xlen=32
.option push
-.option arch, rv32\base\string
+.option arch, rv\xlen\base\string
nop
.option pop
.endm
@@ -50,13 +50,6 @@ imply zve32x_zvl256b
imply zve32x_zvl128b
imply zve32x_zvl64b
-imply zcb
-imply zcd
-imply zcf
-imply zcmp
-imply zcmop
-imply zcmt
-
imply zicfilp
imply zicfiss
@@ -72,6 +65,9 @@ imply h
imply zhinx
imply zhinxmin
+imply zcd
+imply zcf
+
imply q
imply zqinx
@@ -85,6 +81,21 @@ imply zfhmin
imply zfinx
imply f
+imply zce,if,32
+imply zce,if,64
+imply zce,id,32
+imply zce,id,64
+imply zce
+imply zcb
+imply zcmp
+imply zcmop
+imply zcmt
+imply c,if,32
+imply c,if,64
+imply c,id,32
+imply c,id,64
+imply c
+
imply b
imply zk
diff --git a/gas/testsuite/gas/riscv/mapping-symbols.d b/gas/testsuite/gas/riscv/mapping-symbols.d
index ab1d470..ddc1502 100644
--- a/gas/testsuite/gas/riscv/mapping-symbols.d
+++ b/gas/testsuite/gas/riscv/mapping-symbols.d
@@ -9,43 +9,43 @@ 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+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+02 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 \$xrv32i2p1_c2p0_zca1p0
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 \$xrv32i2p1_c2p0
+0+0a l .text.section.padding 0+00 \$xrv32i2p1_c2p0_zca1p0
0+03 l .text.odd.align.start.insn 0+00 \$d
0+04 l .text.odd.align.start.insn 0+00 \$xrv32i2p1
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/mapping-x.s b/gas/testsuite/gas/riscv/mapping-x.s
index f17cf22..2131253 100644
--- a/gas/testsuite/gas/riscv/mapping-x.s
+++ b/gas/testsuite/gas/riscv/mapping-x.s
@@ -1,5 +1,5 @@
.attribute arch, "rv32ic"
-.option arch, -c
+.option norvc
.insn 4, 0x00000013
$x:
.insn 2, 0x0001
diff --git a/gas/testsuite/gas/riscv/mapping.s b/gas/testsuite/gas/riscv/mapping.s
index 0382cfc..c8ed24c 100644
--- a/gas/testsuite/gas/riscv/mapping.s
+++ b/gas/testsuite/gas/riscv/mapping.s
@@ -11,7 +11,7 @@ j funcA # rv32ic
.globl funcB
funcB:
addi a0, zero, 2 # rv32ic, need to be added since start of section
-.option arch, -c
+.option norvc
j funcB # rv32i
.option pop
@@ -35,7 +35,7 @@ addi a0, zero, 2 # $x, but same as previous addi, so removed
.option arch, +c
addi a0, zero, 1 # $xrv32ic
.byte 1 # $d
-.option arch, -c
+.option norvc
.align 3 # odd alignment, $x replaced by $d + $x
addi a0, zero, 2 # $xrv32i
.option pop
@@ -81,7 +81,7 @@ addi a0, zero, 2
.align 2 # $xrv32ic, .align and .fill are in the different frag, so neither be removed,
# but will be removed in riscv_check_mapping_symbols
.fill 1, 0, 0 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
-.option arch, -c
+.option norvc
addi a0, zero, 1 # $xrv32i
addi a0, zero, 2
.option pop
@@ -89,7 +89,7 @@ addi a0, zero, 2
.section .text.last.section, "ax"
.option push
.option norelax
-.option arch, -c
+.option norvc
addi a0, zero, 1 # $xrv32i
.word 1 # $d
.align 2 # zero section padding, $x at the end of section, removed in riscv_check_mapping_symbols
@@ -112,7 +112,7 @@ addi a0, zero, 2 # $xrv32iac
.option arch, rv32ic
.balign 4 # $xrv32ic, add at the start of section
addi a0, zero, 1 # $x, won't added
-.option arch, -c
+.option norvc
.align 3 # $x, won't added
addi a0, zero, 2 # $xrv32i
.option pop
diff --git a/gas/testsuite/gas/riscv/march-imply-zce-f-32.d b/gas/testsuite/gas/riscv/march-imply-zce-f-32.d
deleted file mode 100644
index e0cca82..0000000
--- a/gas/testsuite/gas/riscv/march-imply-zce-f-32.d
+++ /dev/null
@@ -1,6 +0,0 @@
-#as: -march=rv32if_zce -march-attr -misa-spec=20191213
-#readelf: -A
-#source: empty.s
-Attribute Section: riscv
-File Attributes
- Tag_RISCV_arch: "rv32i2p1_f2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcf1p0_zcmp1p0_zcmt1p0"
diff --git a/gas/testsuite/gas/riscv/march-imply-zce-f-64.d b/gas/testsuite/gas/riscv/march-imply-zce-f-64.d
deleted file mode 100644
index f0ccd7a..0000000
--- a/gas/testsuite/gas/riscv/march-imply-zce-f-64.d
+++ /dev/null
@@ -1,6 +0,0 @@
-#as: -march=rv64if_zce -march-attr -misa-spec=20191213
-#readelf: -A
-#source: empty.s
-Attribute Section: riscv
-File Attributes
- Tag_RISCV_arch: "rv64i2p1_f2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0"
diff --git a/gas/testsuite/gas/riscv/march-imply-zce.d b/gas/testsuite/gas/riscv/march-imply-zce.d
deleted file mode 100644
index fd1cd3f..0000000
--- a/gas/testsuite/gas/riscv/march-imply-zce.d
+++ /dev/null
@@ -1,6 +0,0 @@
-#as: -march=rv32i_zce -march-attr -misa-spec=20191213
-#readelf: -A
-#source: empty.s
-Attribute Section: riscv
-File Attributes
- Tag_RISCV_arch: "rv32i2p1_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0"
diff --git a/gas/testsuite/gas/riscv/march-ok-reorder.d b/gas/testsuite/gas/riscv/march-ok-reorder.d
index 712c1bd..883d6a2 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 8c1f665..27df69d 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 e4b603b..bee01f1 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 d83f01d..191f088 100644
--- a/gas/testsuite/gas/riscv/option-arch-fail.l
+++ b/gas/testsuite/gas/riscv/option-arch-fail.l
@@ -1,8 +1,9 @@
.*Assembler messages:
.*Error: m2p0: ISA string must begin with rv32, rv64 or Profiles
-.*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: deprecated \- extension `i' in .option arch `\-i'
+.*Error: cannot \+ base extension `e' in .option arch `\+e'
+.*Error: deprecated \- extension `g' in .option arch `\-g'
+.*Error: deprecated \- extension `c' in .option arch `\-c'
.*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 `\+'
diff --git a/gas/testsuite/gas/riscv/option-arch-fail.s b/gas/testsuite/gas/riscv/option-arch-fail.s
index 101587a..2ba7a16 100644
--- a/gas/testsuite/gas/riscv/option-arch-fail.s
+++ b/gas/testsuite/gas/riscv/option-arch-fail.s
@@ -4,6 +4,7 @@
.option arch, -i
.option arch, +e
.option arch, -g
+.option arch, -c
.option arch, +zsubset2p0
.option arch, +f2p0_d2p0
.option arch, +
diff --git a/gas/testsuite/gas/riscv/option-arch.s b/gas/testsuite/gas/riscv/option-arch.s
index a37659f..8836bc1 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 norvc
add a0, a0, a1 # func-level, rv64i_d2p0_xvendor1p0
frcsr a0
.option pop
diff --git a/gas/testsuite/gas/riscv/option-norvc.d b/gas/testsuite/gas/riscv/option-norvc.d
index 6f36ed6..5a4b976 100644
--- a/gas/testsuite/gas/riscv/option-norvc.d
+++ b/gas/testsuite/gas/riscv/option-norvc.d
@@ -8,11 +8,11 @@ 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
-0+06 l .text 0+00 \$xrv32i2p0_f2p0_c2p0
+0+06 l .text 0+00 \$xrv32i2p0_f2p0_c2p0_zca1p0_zcf1p0
0+08 l .text 0+00 \$xrv32i2p0_f2p0
-0+0c l .text 0+00 \$xrv64i2p0_f2p0_d2p0_c2p0
+0+0c l .text 0+00 \$xrv64i2p0_f2p0_d2p0_c2p0_zca1p0_zcd1p0
0+0e l .text 0+00 \$xrv64i2p0_f2p0_d2p0
0+12 l .text 0+00 \$xrv64i2p0_f2p0_d2p0_zca1p0
0+14 l .text 0+00 \$xrv64i2p0_f2p0_d2p0
diff --git a/gas/testsuite/gas/riscv/shamt-32.s b/gas/testsuite/gas/riscv/shamt-32.s
index a673f88..9fa18fb 100644
--- a/gas/testsuite/gas/riscv/shamt-32.s
+++ b/gas/testsuite/gas/riscv/shamt-32.s
@@ -1,4 +1,4 @@
- .option arch, -c
+ .option norvc
slli a0, a0, 0
slli a0, a0, 31
slli a0, a0, 32
diff --git a/gas/testsuite/gas/riscv/shamt-64.s b/gas/testsuite/gas/riscv/shamt-64.s
index 8878318..5ca5e6d 100644
--- a/gas/testsuite/gas/riscv/shamt-64.s
+++ b/gas/testsuite/gas/riscv/shamt-64.s
@@ -1,4 +1,4 @@
- .option arch, -c
+ .option norvc
slli a0, a0, 0
slli a0, a0, 31
slli a0, a0, 32
diff --git a/include/doubly-linked-list.h b/include/doubly-linked-list.h
new file mode 100644
index 0000000..3f5ea28
--- /dev/null
+++ b/include/doubly-linked-list.h
@@ -0,0 +1,447 @@
+/* Manipulate doubly linked lists.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+#ifndef _DOUBLY_LINKED_LIST_H
+#define _DOUBLY_LINKED_LIST_H
+
+/* Doubly linked list implementation enforcing typing.
+
+ This implementation of doubly linked list tries to achieve the enforcement of
+ typing similarly to C++ templates, but without encapsulation.
+
+ All the functions are prefixed with the type of the value: "AType_xxx".
+ Some functions are prefixed with "_AType_xxx" and are not part of the public
+ API, so should not be used, except for _##LTYPE##_merge_sort with a caveat
+ (see note above its definition).
+
+ Each function (### is a placeholder for method name) has a macro for:
+ (1) its invocation LINKED_LIST_###(LTYPE).
+ (2) its prototype LINKED_LIST_DECL_###(A, A2, scope). To add in a header
+ file, or a source file for forward declaration. 'scope' should be set
+ respectively to 'extern', or 'static'.
+ (3) its definition LINKED_LIST_DEFN_###(A, A2, scope). To add in a source
+ file with the 'scope' set respectively to nothing, or 'static' depending
+ on (2).
+
+ Data structures requirements:
+ - LTYPE corresponds to the node of a doubly linked list. It needs to define
+ attributes 'prev' and 'next' which are pointers on the type of a node.
+ For instance:
+ struct my_list_node
+ {
+ T value;
+ struct my_list_node *prev;
+ struct my_list_node *next;
+ };
+ - LWRAPPERTYPE is a structure wrapping the nodes and others metadata (first,
+ last, size).
+ */
+
+
+/* Mutative operations:
+ - append
+ - prepend
+ - insert_before
+ - pop_front
+ - pop_back
+ - remove
+ - swap
+ The header and body of each of those operation can be declared individually,
+ or as a whole via LINKED_LIST_MUTATIVE_OPS_PROTOTYPE for the prototypes, and
+ LINKED_LIST_MUTATIVE_OPS_DECL for the implementations. */
+
+/* Append the given node new_ to the exising list.
+ Precondition: prev and next of new_ must be NULL. */
+#define LINKED_LIST_APPEND(LTYPE) LTYPE##_append
+
+#define LINKED_LIST_DECL_APPEND(LWRAPPERTYPE, LTYPE, EXPORT) \
+ EXPORT void \
+ LTYPE##_append (LWRAPPERTYPE *wrapper, LTYPE *new_)
+
+#define LINKED_LIST_DEFN_APPEND(LWRAPPERTYPE, LTYPE, EXPORT) \
+EXPORT void \
+LTYPE##_append (LWRAPPERTYPE *wrapper, LTYPE *new_) \
+{ \
+ if (wrapper->last == NULL) \
+ wrapper->first = new_; \
+ else \
+ { \
+ new_->prev = wrapper->last; \
+ wrapper->last->next = new_; \
+ } \
+ wrapper->last = new_; \
+ ++wrapper->size; \
+}
+
+/* Prepend the given node new_ to the existing list.
+ Precondition: prev and next of new_ must be NULL. */
+#define LINKED_LIST_PREPEND(LTYPE) LTYPE##_prepend
+
+#define LINKED_LIST_DECL_PREPEND(LWRAPPERTYPE, LTYPE, EXPORT) \
+ EXPORT void \
+ LTYPE##_prepend (LWRAPPERTYPE *wrapper, LTYPE *new_)
+
+#define LINKED_LIST_DEFN_PREPEND(LWRAPPERTYPE, LTYPE, EXPORT) \
+EXPORT void \
+LTYPE##_prepend (LWRAPPERTYPE *wrapper, LTYPE *new_) \
+{ \
+ if (wrapper->first == NULL) \
+ wrapper->last = new_; \
+ else \
+ { \
+ new_->next = wrapper->first; \
+ wrapper->first->prev = new_; \
+ } \
+ wrapper->first = new_; \
+ ++wrapper->size; \
+}
+
+/* Insert the given node new_ before 'where' in the existing list.
+ If where == NULL, the insertion is equivalent to an append.
+ If where == first, the insertion is equivalent to a prepend. */
+#define LINKED_LIST_INSERT_BEFORE(LTYPE) LTYPE##_insert_before
+
+#define LINKED_LIST_DECL_INSERT_BEFORE(LWRAPPERTYPE, LTYPE, EXPORT) \
+ EXPORT void \
+ LTYPE##_insert_before (LWRAPPERTYPE *wrapper, \
+ LTYPE *new_, \
+ LTYPE *where)
+
+#define LINKED_LIST_DEFN_INSERT_BEFORE(LWRAPPERTYPE, LTYPE, EXPORT) \
+EXPORT void \
+LTYPE##_insert_before (LWRAPPERTYPE *wrapper, \
+ LTYPE *new_, \
+ LTYPE *where) \
+{ \
+ if (where == wrapper->first) \
+ LTYPE##_prepend (wrapper, new_); \
+ else if (where == NULL) \
+ LTYPE##_append (wrapper, new_); \
+ else \
+ { \
+ where->prev->next = new_; \
+ new_->prev = where->prev; \
+ where->prev = new_; \
+ new_->next = where; \
+ ++wrapper->size; \
+ } \
+}
+
+/* Pop the first node of the list. */
+#define LINKED_LIST_POP_FRONT(LTYPE) LTYPE##_pop_front
+
+#define LINKED_LIST_DECL_POP_FRONT(LWRAPPERTYPE, LTYPE, EXPORT) \
+ EXPORT LTYPE * \
+ LTYPE##_pop_front (LWRAPPERTYPE *wrapper)
+
+#define LINKED_LIST_DEFN_POP_FRONT(LWRAPPERTYPE, LTYPE, EXPORT) \
+EXPORT LTYPE * \
+LTYPE##_pop_front (LWRAPPERTYPE *wrapper) \
+{ \
+ LTYPE *front_node = wrapper->first; \
+ if (front_node != NULL) \
+ { \
+ wrapper->first = front_node->next; \
+ if (wrapper->last == front_node) \
+ wrapper->last = NULL; \
+ else \
+ { \
+ front_node->next->prev = NULL; \
+ front_node->next = NULL; \
+ } \
+ front_node->next = NULL; \
+ --wrapper->size; \
+ } \
+ return front_node; \
+}
+
+/* Pop the last node of the list. */
+#define LINKED_LIST_POP_BACK(LTYPE) LTYPE##_pop_back
+
+#define LINKED_LIST_DECL_POP_BACK(LWRAPPERTYPE, LTYPE, EXPORT) \
+ EXPORT LTYPE * \
+ LTYPE##_pop_back (LWRAPPERTYPE *wrapper)
+
+#define LINKED_LIST_DEFN_POP_BACK(LWRAPPERTYPE, LTYPE, EXPORT) \
+EXPORT LTYPE * \
+LTYPE##_pop_back (LWRAPPERTYPE *wrapper) \
+{ \
+ LTYPE *back_node = wrapper->last; \
+ if (back_node != NULL) \
+ { \
+ wrapper->last = back_node->prev; \
+ if (wrapper->first == back_node) \
+ wrapper->first = NULL; \
+ else \
+ { \
+ back_node->prev->next = NULL; \
+ back_node->prev = NULL; \
+ } \
+ back_node->prev = NULL; \
+ --wrapper->size; \
+ } \
+ return back_node; \
+}
+
+/* Remove the given node from the existing list, and return the previous
+ node. */
+#define LINKED_LIST_REMOVE(LTYPE) LTYPE##_remove
+
+#define LINKED_LIST_DECL_REMOVE(LWRAPPERTYPE, LTYPE, EXPORT) \
+ EXPORT LTYPE * \
+ LTYPE##_remove (LWRAPPERTYPE *wrapper, LTYPE *node)
+
+#define LINKED_LIST_DEFN_REMOVE(LWRAPPERTYPE, LTYPE, EXPORT) \
+EXPORT LTYPE * \
+LTYPE##_remove (LWRAPPERTYPE *wrapper, LTYPE *node) \
+{ \
+ LTYPE *previous = NULL; \
+ \
+ if (node->prev != NULL) \
+ { \
+ node->prev->next = node->next; \
+ if (node->next == NULL) \
+ wrapper->last = node->prev; \
+ else \
+ node->next->prev = node->prev; \
+ previous = node->prev; \
+ node->next = NULL; \
+ node->prev = NULL; \
+ --wrapper->size; \
+ } \
+ else \
+ LTYPE##_pop_front (wrapper); \
+ \
+ return previous; \
+}
+
+/* Generic swap. */
+#define LINKED_LIST_SWAP(LTYPE) LTYPE##_swap
+
+#define LINKED_LIST_DECL_SWAP(LWRAPPERTYPE, LTYPE, EXPORT) \
+ EXPORT void \
+ LTYPE##_swap (LWRAPPERTYPE *wrapper, LTYPE *node1, LTYPE *node2)
+
+/* Swap two nodes in a list. */
+#define LINKED_LIST_DEFN_SWAP(LWRAPPERTYPE, LTYPE, EXPORT) \
+EXPORT void \
+LTYPE##_swap (LWRAPPERTYPE *wrapper, LTYPE *node1, LTYPE *node2) \
+{ \
+ LTYPE *prev1 = node1->prev; \
+ LTYPE *next1 = node1->next; \
+ LTYPE *prev2 = node2->prev; \
+ LTYPE *next2 = node2->next; \
+ \
+ if (prev1 != NULL) \
+ prev1->next = node2; \
+ else \
+ wrapper->first = node2; \
+ if (prev2 != NULL) \
+ prev2->next = node1; \
+ else \
+ wrapper->first = node1; \
+ \
+ if (next1 != NULL) \
+ next1->prev = node2; \
+ else \
+ wrapper->last = node2; \
+ if (next2 != NULL) \
+ next2->prev = node1; \
+ else \
+ wrapper->last = node1; \
+ \
+ { \
+ LTYPE *temp = node1->next; \
+ node1->next = node2->next; \
+ node2->next = temp; \
+ } \
+ { \
+ LTYPE *temp = node1->prev; \
+ node1->prev = node2->prev; \
+ node2->prev = temp; \
+ } \
+}
+
+/* Note: all the mutative operations below also update the data in the wrapper,
+ i.e. first, last and size. */
+#define LINKED_LIST_MUTATIVE_OPS_PROTOTYPE(LWRAPPERTYPE, LTYPE, EXPORT) \
+ LINKED_LIST_DECL_APPEND(LWRAPPERTYPE, LTYPE, EXPORT); \
+ LINKED_LIST_DECL_PREPEND(LWRAPPERTYPE, LTYPE, EXPORT); \
+ LINKED_LIST_DECL_INSERT_BEFORE(LWRAPPERTYPE, LTYPE, EXPORT); \
+ LINKED_LIST_DECL_POP_FRONT(LWRAPPERTYPE, LTYPE, EXPORT); \
+ LINKED_LIST_DECL_POP_BACK(LWRAPPERTYPE, LTYPE, EXPORT); \
+ LINKED_LIST_DECL_REMOVE(LWRAPPERTYPE, LTYPE, EXPORT); \
+ LINKED_LIST_DECL_SWAP(LWRAPPERTYPE, LTYPE, EXPORT)
+
+#define LINKED_LIST_MUTATIVE_OPS_DECL(LWRAPPERTYPE, LTYPE, EXPORT) \
+ LINKED_LIST_DEFN_APPEND(LWRAPPERTYPE, LTYPE, EXPORT) \
+ LINKED_LIST_DEFN_PREPEND(LWRAPPERTYPE, LTYPE, EXPORT) \
+ LINKED_LIST_DEFN_INSERT_BEFORE(LWRAPPERTYPE, LTYPE, EXPORT) \
+ LINKED_LIST_DEFN_POP_FRONT(LWRAPPERTYPE, LTYPE, EXPORT) \
+ LINKED_LIST_DEFN_POP_BACK(LWRAPPERTYPE, LTYPE, EXPORT) \
+ LINKED_LIST_DEFN_REMOVE(LWRAPPERTYPE, LTYPE, EXPORT) \
+ LINKED_LIST_DEFN_SWAP(LWRAPPERTYPE, LTYPE, EXPORT)
+
+
+/* Sorting. */
+
+#define LINKED_LIST_MERGE_SORT_(LTYPE) LTYPE##_merge_sort_
+
+#define LINKED_LIST_MERGE_SORT(LTYPE) LTYPE##_merge_sort
+
+#define LINKED_LIST_MERGE_SORT_PROTOTYPE_(LTYPE, EXPORT) \
+ EXPORT LTYPE * \
+ LTYPE##_merge_sort_ (LTYPE *node, \
+ int (*fn_cmp) (const LTYPE *, const LTYPE *))
+
+#define LINKED_LIST_MERGE_SORT_PROTOTYPE(LWRAPPERTYPE, LTYPE, EXPORT) \
+ EXPORT void \
+ LTYPE##_merge_sort (LWRAPPERTYPE *wrapper, \
+ int (*fn_cmp) (const LTYPE *, const LTYPE *))
+
+/* Note: all the functions and macros below starting with "_" should be
+ considered private. */
+
+/* Compute the middle element of the list based on the turtle and hare
+ approach, i.e. the hare runs twice faster than the turtle. */
+#define _MERGE_SORT_IMPL_COMPUTE_TURTLE(LTYPE) \
+static inline LTYPE * \
+LTYPE##_merge_sort_compute_turtle_ (LTYPE *node) \
+{ \
+ if (node == NULL) \
+ return node; \
+ \
+ LTYPE *turtle = node, *hare = node->next; \
+ while (hare != NULL && hare->next != NULL) \
+ { \
+ turtle = turtle->next; \
+ hare = hare->next->next; \
+ } \
+ return turtle; \
+}
+
+/* Append n at the end of l_out, and return the next node after n.
+ l_out and l_last should be ideally encapsulated into a list structure
+ but this is overkill for what we need here. */
+#define _MERGE_SORT_IMPL_OUT_APPEND(LTYPE) \
+static inline LTYPE * \
+LTYPE##_merge_sort_out_append_ (LTYPE **l_out, LTYPE **l_last, \
+ LTYPE *n) \
+{ \
+ if (*l_last == NULL) \
+ { \
+ *l_last = n; \
+ *l_out = n; \
+ n->prev = NULL; \
+ } \
+ else \
+ { \
+ (*l_last)->next = n; \
+ n->prev = *l_last; \
+ *l_last = n; \
+ } \
+ \
+ return n->next; \
+}
+
+/* Merge two sorted lists together.
+ The returned value corresponds to the first element of the list.
+ Note: both input lists are invalidated after the call. */
+#define _MERGE_SORT_IMPL_MERGE(LTYPE) \
+static inline LTYPE * \
+LTYPE##_merge_sort_merge_ (LTYPE *l_left, LTYPE *l_right, \
+ int (*fn_cmp) (const LTYPE *, const LTYPE *))\
+{ \
+ if (l_left == NULL) \
+ return l_right; \
+ else if (l_right == NULL) \
+ return l_left; \
+ \
+ LTYPE *l_out = NULL, *l_last = NULL; \
+ \
+ LTYPE *l_l = l_left, *l_r = l_right; \
+ while (l_l != NULL && l_r != NULL) \
+ { \
+ int cmp = fn_cmp (l_l, l_r); \
+ if (cmp <= 0) \
+ l_l = LTYPE##_merge_sort_out_append_ (&l_out, &l_last, l_l); \
+ else \
+ l_r = LTYPE##_merge_sort_out_append_ (&l_out, &l_last, l_r); \
+ } \
+ \
+ LTYPE *l_remaining = (l_l != NULL) ? l_l : l_r; \
+ while (l_remaining != NULL) \
+ l_remaining = \
+ LTYPE##_merge_sort_out_append_ (&l_out, &l_last, l_remaining); \
+ \
+ return l_out; \
+}
+
+/* Merge sort implementation taking the first node of the list to sort,
+ and the comparison function. Returns the first node of the sorted list.
+ Note: use this if you don't care about updating the information in the
+ wrapper. */
+#define _MERGE_SORT_DEFN_SORT(LTYPE, EXPORT) \
+EXPORT LTYPE * \
+LTYPE##_merge_sort_ (LTYPE *node, \
+ int (*fn_cmp)(const LTYPE *, const LTYPE *)) \
+{ \
+ if (node == NULL) \
+ return NULL; \
+ else if (node->next == NULL) \
+ return node; \
+ \
+ LTYPE *left_end = LTYPE##_merge_sort_compute_turtle_ (node); \
+ LTYPE *left_begin = node; \
+ LTYPE *right_begin = left_end->next; \
+ /* break the list. */ \
+ left_end->next = NULL; \
+ right_begin->prev = NULL; \
+ \
+ left_begin = LTYPE##_merge_sort_ (left_begin, fn_cmp); \
+ right_begin = LTYPE##_merge_sort_ (right_begin, fn_cmp); \
+ return LTYPE##_merge_sort_merge_ (left_begin, right_begin, fn_cmp); \
+}
+
+/* Merge sort wrapper that the end-user should be using as it updates the
+ first and last metadata of the list in wrapper as well.
+ If the user does not want to pay the cost of the update of the data,
+ it can directly use _##LTYPE##_merge_sort_merge. */
+#define _MERGE_SORT_DEFN_WRAPPER_SORT(LWRAPPERTYPE, LTYPE, EXPORT) \
+EXPORT void \
+LTYPE##_merge_sort (LWRAPPERTYPE *wrapper, \
+ int (*fn_cmp) (const LTYPE *, const LTYPE *)) \
+{ \
+ wrapper->first = LTYPE##_merge_sort_ (wrapper->first, fn_cmp); \
+ \
+ if (wrapper->first == NULL || wrapper->first->next == NULL) \
+ wrapper->last = wrapper->first; \
+ else \
+ for (LTYPE *node = wrapper->first; \
+ node != NULL; \
+ node = node->next) \
+ wrapper->last = node; \
+}
+
+#define LINKED_LIST_MERGE_SORT_DECL(LWRAPPERTYPE, LTYPE, EXPORT) \
+ _MERGE_SORT_IMPL_COMPUTE_TURTLE(LTYPE) \
+ _MERGE_SORT_IMPL_OUT_APPEND(LTYPE) \
+ _MERGE_SORT_IMPL_MERGE(LTYPE) \
+ _MERGE_SORT_DEFN_SORT(LTYPE, EXPORT) \
+ _MERGE_SORT_DEFN_WRAPPER_SORT(LWRAPPERTYPE, LTYPE, EXPORT)
+
+#endif /* _DOUBLY_LINKED_LIST_H */
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 2b146af..858fcce 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -493,18 +493,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/include/sframe-api.h b/include/sframe-api.h
index 753a91f..3dc18b6 100644
--- a/include/sframe-api.h
+++ b/include/sframe-api.h
@@ -36,11 +36,6 @@ typedef struct sframe_encoder_ctx sframe_encoder_ctx;
#define MAX_OFFSET_BYTES \
((SFRAME_FRE_OFFSET_4B * 2 * MAX_NUM_STACK_OFFSETS))
-/* Set of flags that are required to be harmonious between all decoder and
- encoder objects participating in a link. */
-#define SFRAME_F_LD_MUSTHAVE_FLAGS \
- (SFRAME_F_FDE_FUNC_START_PCREL)
-
/* User interfacing SFrame Row Entry.
An abstraction provided by libsframe so the consumer is decoupled from
the binary format representation of the same.
diff --git a/include/sframe-internal.h b/include/sframe-internal.h
new file mode 100644
index 0000000..a246f26
--- /dev/null
+++ b/include/sframe-internal.h
@@ -0,0 +1,30 @@
+/* Internal header for SFrame.
+
+ Used by GNU as and ld.
+
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _SFRAME_INTERNAL_H
+#define _SFRAME_INTERNAL_H
+
+#include "sframe.h"
+
+/* Set of flags which are required to be harmonious between GNU as and ld. All
+ objects participating in the link for GNU ld must have these flags set. */
+#define SFRAME_V2_GNU_AS_LD_ENCODING_FLAGS \
+ (SFRAME_F_FDE_FUNC_START_PCREL)
+
+#endif /* _SFRAME_INTERNAL_H */
diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in
index 387975d..d507f27 100644
--- a/libiberty/Makefile.in
+++ b/libiberty/Makefile.in
@@ -237,6 +237,7 @@ CONFIGURED_OFILES = ./asprintf.$(objext) ./atexit.$(objext) \
INSTALLED_HEADERS = \
$(INCDIR)/ansidecl.h \
$(INCDIR)/demangle.h \
+ $(INCDIR)/doubly-linked-list.h \
$(INCDIR)/dyn-string.h \
$(INCDIR)/fibheap.h \
$(INCDIR)/floatformat.h \
diff --git a/libiberty/testsuite/Makefile.in b/libiberty/testsuite/Makefile.in
index 2b0883c..ef549ca 100644
--- a/libiberty/testsuite/Makefile.in
+++ b/libiberty/testsuite/Makefile.in
@@ -45,7 +45,8 @@ all:
check: @CHECK@
really-check: check-cplus-dem check-d-demangle check-rust-demangle \
- check-pexecute check-expandargv check-strtol
+ check-pexecute check-expandargv check-strtol \
+ check-doubly-linked-list
# Run some tests of the demangler.
check-cplus-dem: test-demangle $(srcdir)/demangle-expected
@@ -69,6 +70,10 @@ check-expandargv: test-expandargv
check-strtol: test-strtol
./test-strtol
+# Check the linked list functionality
+check-doubly-linked-list: test-doubly-linked-list
+ ./test-doubly-linked-list
+
# Run the demangler fuzzer
fuzz-demangler: demangler-fuzzer
./demangler-fuzzer
@@ -90,6 +95,10 @@ test-strtol: $(srcdir)/test-strtol.c ../libiberty.a
$(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-strtol \
$(srcdir)/test-strtol.c ../libiberty.a
+test-doubly-linked-list: $(srcdir)/test-doubly-linked-list.c
+ $(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-doubly-linked-list \
+ $(srcdir)/test-doubly-linked-list.c
+
demangler-fuzzer: $(srcdir)/demangler-fuzzer.c ../libiberty.a
$(TEST_COMPILE) -o demangler-fuzzer \
$(srcdir)/demangler-fuzzer.c ../libiberty.a
@@ -104,6 +113,7 @@ mostlyclean:
rm -f test-pexecute
rm -f test-expandargv
rm -f test-strtol
+ rm -f test-doubly-linked-list
rm -f demangler-fuzzer
rm -f core
clean: mostlyclean
diff --git a/libiberty/testsuite/test-doubly-linked-list.c b/libiberty/testsuite/test-doubly-linked-list.c
new file mode 100644
index 0000000..1e1fc63
--- /dev/null
+++ b/libiberty/testsuite/test-doubly-linked-list.c
@@ -0,0 +1,269 @@
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "doubly-linked-list.h"
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#endif
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
+/* Implementation */
+
+typedef int T;
+
+typedef struct ListNodeType
+{
+ T value;
+ struct ListNodeType *next;
+ struct ListNodeType *prev;
+} ListNodeType;
+
+ListNodeType * l_new_node (T value)
+{
+ ListNodeType *n = malloc (sizeof (ListNodeType));
+ n->next = NULL;
+ n->prev = NULL;
+ n->value = value;
+ return n;
+}
+
+typedef struct LinkedListWrapperType
+{
+ ListNodeType *first;
+ ListNodeType *last;
+ size_t size;
+} LinkedListWrapperType;
+
+int compare_nodes (const ListNodeType *n1, const ListNodeType *n2)
+{
+ if (n1->value == n2->value)
+ return 0;
+ else if (n1->value < n2->value)
+ return -1;
+ else
+ return 1;
+}
+
+LINKED_LIST_MUTATIVE_OPS_PROTOTYPE (LinkedListWrapperType, ListNodeType, static);
+LINKED_LIST_MERGE_SORT_PROTOTYPE (LinkedListWrapperType, ListNodeType, static);
+
+LINKED_LIST_MUTATIVE_OPS_DECL (LinkedListWrapperType, ListNodeType, static)
+LINKED_LIST_MERGE_SORT_DECL (LinkedListWrapperType, ListNodeType, static)
+
+ListNodeType * find_last_node (ListNodeType *head)
+{
+ if (head == NULL)
+ return NULL;
+
+ ListNodeType *n = head;
+ while (n->next != NULL)
+ n = n->next;
+
+ return n;
+}
+
+void l_print (ListNodeType *node)
+{
+ for (ListNodeType *l = node; l != NULL; l = l->next)
+ printf ("%d ", l->value);
+ printf ("\n");
+}
+
+void l_reverse_print (ListNodeType *last_node)
+{
+ for (ListNodeType *l = last_node; l != NULL; l = l->prev)
+ printf ("%d ", l->value);
+ printf ("\n");
+}
+
+struct test_data_t
+{
+ T const *content;
+ size_t size;
+};
+
+bool run_test (const struct test_data_t *expect,
+ LinkedListWrapperType *current,
+ bool reversed)
+{
+ ListNodeType *node = (reversed) ? current->last : current->first;
+ bool passed = true;
+ for (int i=0; i<expect->size && node != NULL; ++i)
+ {
+ if (reversed)
+ {
+ if (expect->content[expect->size - 1 - i] != node->value)
+ {
+ printf ("FAIL: mismatching expected (%d) VS current (%d).\n",
+ expect->content[expect->size - 1 - i], node->value);
+ passed = false;
+ }
+ if (node->prev == NULL && current->first != node)
+ {
+ printf ("FAIL: first is not matching the first node.\n");
+ passed = false;
+ }
+ }
+ else
+ {
+ if (expect->content[i] != node->value)
+ {
+ printf ("FAIL: mismatching expected (%d) VS current (%d).\n",
+ expect->content[i], node->value);
+ passed = false;
+ }
+ if (node->next == NULL && current->last != node)
+ {
+ printf ("FAIL: last_ is not matching the last node.\n");
+ passed = false;
+ }
+ }
+
+ if (!passed)
+ return false;
+
+ if (reversed)
+ node = node->prev;
+ else
+ node = node->next;
+ }
+
+ if (node != NULL)
+ {
+ printf ("FAIL: the list is longer than expected.\n");
+ passed = false;
+ }
+ if (expect->size != current->size)
+ {
+ printf ("FAIL: size (%ld) is not matching the real size of the list (%ld).\n",
+ current->size, expect->size);
+ passed = false;
+ }
+
+ return passed;
+}
+
+bool check(const char *op,
+ const struct test_data_t *expect,
+ LinkedListWrapperType *wrapper)
+{
+ bool success = true;
+ bool res;
+
+ l_print (wrapper->first);
+ res = run_test (expect, wrapper, false);
+ printf ("%s: test-linked-list::%s: check forward conformity\n",
+ res ? "PASS": "FAIL", op);
+ success &= res;
+
+ l_reverse_print (wrapper->last);
+ res = run_test (expect, wrapper, true);
+ printf ("%s: test-linked-list::%s: check backward conformity\n",
+ res ? "PASS": "FAIL", op);
+ success &= res;
+
+ printf("\n");
+
+ return success;
+}
+
+const int EXPECT_0 [] = { 10, 4, 3, 1, 9, 2 };
+const int EXPECT_1 [] = { 1, 2, 3, 4, 9, 10 };
+const int EXPECT_2 [] = { 11, 1, 2, 3, 4, 9, 10 };
+const int EXPECT_3 [] = { 11, 1, 2, 3, 4, 9, 8, 10 };
+const int EXPECT_4 [] = { 11, 2, 3, 4, 9, 8, 10 };
+const int EXPECT_5 [] = { 10, 2, 3, 4, 9, 8, 11 };
+const int EXPECT_6 [] = { 10, 3, 2, 4, 9, 8, 11 };
+const int EXPECT_7 [] = { 10, 9, 2, 4, 3, 8, 11 };
+const int EXPECT_8 [] = { 2, 3, 4, 8, 9, 10, 11 };
+const int EXPECT_9 [] = { 3, 4, 8, 9, 10, 11 };
+const int EXPECT_10 [] = { 3, 4, 8, 9, 10 };
+const struct test_data_t test_data[] = {
+ { .content = EXPECT_0, .size = sizeof(EXPECT_0) / sizeof(EXPECT_0[0]) },
+ { .content = EXPECT_1, .size = sizeof(EXPECT_1) / sizeof(EXPECT_1[0]) },
+ { .content = EXPECT_2, .size = sizeof(EXPECT_2) / sizeof(EXPECT_2[0]) },
+ { .content = EXPECT_3, .size = sizeof(EXPECT_3) / sizeof(EXPECT_3[0]) },
+ { .content = EXPECT_4, .size = sizeof(EXPECT_4) / sizeof(EXPECT_4[0]) },
+ { .content = EXPECT_5, .size = sizeof(EXPECT_5) / sizeof(EXPECT_5[0]) },
+ { .content = EXPECT_6, .size = sizeof(EXPECT_6) / sizeof(EXPECT_6[0]) },
+ { .content = EXPECT_7, .size = sizeof(EXPECT_7) / sizeof(EXPECT_7[0]) },
+ { .content = EXPECT_8, .size = sizeof(EXPECT_8) / sizeof(EXPECT_8[0]) },
+ { .content = EXPECT_9, .size = sizeof(EXPECT_9) / sizeof(EXPECT_9[0]) },
+ { .content = EXPECT_10, .size = sizeof(EXPECT_10) / sizeof(EXPECT_10[0]) },
+};
+
+int main (void)
+{
+ int failures = 0;
+
+ LinkedListWrapperType wrapper = {
+ .first = NULL,
+ .last = NULL,
+ .size = 0,
+ };
+
+ /* Append nodes. */
+ LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (10));
+ LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (4));
+ LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (3));
+ LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (1));
+ LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (9));
+ LINKED_LIST_APPEND(ListNodeType) (&wrapper, l_new_node (2));
+
+ failures += ! check ("append", &test_data[0], &wrapper);
+
+ /* Sort nodes (without updating wrapper). */
+ wrapper.first =
+ LINKED_LIST_MERGE_SORT_(ListNodeType) (wrapper.first, compare_nodes);
+ wrapper.last = find_last_node (wrapper.first);
+
+ failures += ! check ("sort", &test_data[1], &wrapper);
+
+ /* Save a reference to this node for later. */
+ ListNodeType *n_to_remove = wrapper.first;
+
+ /* Prepend node. */
+ LINKED_LIST_PREPEND(ListNodeType) (&wrapper, l_new_node (11));
+ failures += ! check ("prepend", &test_data[2], &wrapper);
+
+ /* Insert node. */
+ LINKED_LIST_INSERT_BEFORE(ListNodeType) (&wrapper, l_new_node (8), wrapper.last);
+ failures += ! check ("insert_before", &test_data[3], &wrapper);
+
+ /* Remove a node. */
+ LINKED_LIST_REMOVE(ListNodeType) (&wrapper, n_to_remove);
+ failures += ! check ("remove", &test_data[4], &wrapper);
+
+ /* Swap first and last. */
+ LINKED_LIST_SWAP(ListNodeType) (&wrapper, wrapper.first, wrapper.last);
+ failures += ! check ("swap first and last", &test_data[5], &wrapper);
+
+ /* Swap adjacent nodes. */
+ LINKED_LIST_SWAP(ListNodeType) (&wrapper, wrapper.first->next,
+ wrapper.first->next->next);
+ failures += ! check ("swap adjacent nodes", &test_data[6], &wrapper);
+
+ /* Swap non-adjacent nodes, but neither first nor last. */
+ LINKED_LIST_SWAP(ListNodeType) (&wrapper, wrapper.first->next,
+ wrapper.first->next->next->next->next);
+ failures += ! check ("swap non-adjacent nodes", &test_data[7], &wrapper);
+
+ /* Sort nodes. */
+ LINKED_LIST_MERGE_SORT(ListNodeType) (&wrapper, compare_nodes);
+ failures += ! check ("sort", &test_data[8], &wrapper);
+
+ /* Pop front. */
+ LINKED_LIST_POP_FRONT(ListNodeType) (&wrapper);
+ failures += ! check ("pop_front", &test_data[9], &wrapper);
+
+ /* Pop back. */
+ LINKED_LIST_POP_BACK(ListNodeType) (&wrapper);
+ failures += ! check ("pop_back", &test_data[10], &wrapper);
+
+ exit (failures ? EXIT_FAILURE : EXIT_SUCCESS);
+}
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index f17d284..56ef62a 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -464,34 +464,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 },
@@ -499,9 +499,9 @@ 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 },
@@ -509,31 +509,31 @@ const struct riscv_opcode riscv_opcodes[] =
{"tail", 0, INSN_CLASS_ZICFILP, "c", (X_T2 << OP_SH_RS1), (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 },
@@ -547,23 +547,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 },
@@ -577,22 +577,22 @@ const struct riscv_opcode riscv_opcodes[] =
{"mips.ehb", 0, INSN_CLASS_XMIPSEXECTL, "", MATCH_MIPS_EHB, MASK_MIPS_EHB, match_opcode, 0 },
{"mips.ihb", 0, INSN_CLASS_XMIPSEXECTL, "", MATCH_MIPS_IHB, MASK_MIPS_IHB, match_opcode, 0 },
{"mips.pause", 0, INSN_CLASS_XMIPSEXECTL, "", MATCH_MIPS_PAUSE, MASK_MIPS_PAUSE, match_opcode, 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 },
@@ -605,16 +605,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 },
/* Zicfilp instructions. */
@@ -639,8 +639,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 },
@@ -657,34 +657,34 @@ 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 },
{"ld", 32, INSN_CLASS_ZCLSD, "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_even_nonzero, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
{"ld", 32, INSN_CLASS_ZCLSD, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_crs2s_even, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
{"ld", 32, INSN_CLASS_ZILSD, "d,o(s)", MATCH_LD, MASK_LD, match_rd_even, INSN_DREF|INSN_8_BYTE },
{"ld", 32, INSN_CLASS_ZILSD, "d,A", 0, (int) M_Lx, match_rd_even_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 },
{"sd", 32, INSN_CLASS_ZCLSD, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_crs2_even, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
{"sd", 32, INSN_CLASS_ZCLSD, "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_crs2s_even, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
{"sd", 32, INSN_CLASS_ZILSD, "t,q(s)", MATCH_SD, MASK_SD, match_rs2_even, INSN_DREF|INSN_8_BYTE },
{"sd", 32, INSN_CLASS_ZILSD, "t,A,s", 0, (int) M_Sx_FSx, match_rs1_nonzero_rs2_even, 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 */
@@ -697,7 +697,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. */
@@ -993,12 +993,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 },
@@ -1055,12 +1055,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 },
@@ -1174,57 +1174,57 @@ 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.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", 32, INSN_CLASS_ZCLSD, "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_even_nonzero, INSN_DREF|INSN_8_BYTE },
-{"c.ldsp", 64, INSN_CLASS_C, "d,Cn(Cc)", MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, INSN_DREF|INSN_8_BYTE },
+{"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", 32, INSN_CLASS_ZCLSD, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_crs2s_even, 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.ld", 64, INSN_CLASS_ZCA, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, INSN_DREF|INSN_8_BYTE },
{"c.sdsp", 32, INSN_CLASS_ZCLSD, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_crs2_even, 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.sdsp", 64, INSN_CLASS_ZCA, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, INSN_DREF|INSN_8_BYTE },
{"c.sd", 32, INSN_CLASS_ZCLSD, "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_crs2s_even, 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.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 },
@@ -3664,39 +3664,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}
diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c
index 4c949c4..172c593 100644
--- a/sim/riscv/sim-main.c
+++ b/sim/riscv/sim-main.c
@@ -1302,7 +1302,7 @@ execute_one (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
case INSN_CLASS_ZAAMO:
case INSN_CLASS_ZALRSC:
return execute_a (cpu, iw, op);
- case INSN_CLASS_C:
+ case INSN_CLASS_ZCA:
/* Check whether model with C extension is selected. */
if (riscv_cpu->csr.misa & 4)
return execute_c (cpu, iw, op);