static const char default_arch[] = DEFAULT_ARCH;
static const char *default_arch_with_ext = DEFAULT_RISCV_ARCH_WITH_EXT;
+static const char *file_arch_str = NULL;
static enum riscv_spec_class default_isa_spec = ISA_SPEC_CLASS_NONE;
static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
true, /* check_unknown_prefixed_ext. */
};
-/* Update the architecture string in the subset_list. */
+/* Update file/function-level architecture string according to the
+ subset_list. */
static void
-riscv_reset_subsets_list_arch_str (void)
+riscv_set_arch_str (const char **arch_str_p)
{
riscv_subset_list_t *subsets = riscv_rps_as.subset_list;
- if (subsets->arch_str != NULL)
- free ((void *) subsets->arch_str);
- subsets->arch_str = riscv_arch_str (xlen, subsets);
+ const char *arch_str = *arch_str_p;
+ if (arch_str != NULL)
+ free ((void *) arch_str);
+ *arch_str_p = riscv_arch_str (xlen, subsets);
}
/* This structure is used to hold a stack of .option values. */
}
riscv_release_subset_list (riscv_rps_as.subset_list);
riscv_parse_subset (&riscv_rps_as, s);
- riscv_reset_subsets_list_arch_str ();
+ riscv_set_arch_str (&file_arch_str);
+ riscv_set_arch_str (&riscv_rps_as.subset_list->arch_str);
riscv_set_rvc (false);
if (riscv_subset_supports (&riscv_rps_as, "c")
if (strcmp (name, "rvc") == 0)
{
riscv_update_subset (&riscv_rps_as, "+c");
- riscv_reset_subsets_list_arch_str ();
+ riscv_set_arch_str (&riscv_rps_as.subset_list->arch_str);
riscv_set_rvc (true);
}
else if (strcmp (name, "norvc") == 0)
{
riscv_update_subset (&riscv_rps_as, "-c");
- riscv_reset_subsets_list_arch_str ();
+ riscv_set_arch_str (&riscv_rps_as.subset_list->arch_str);
riscv_set_rvc (false);
}
else if (strcmp (name, "pic") == 0)
if (ISSPACE (*name) && *name != '\0')
name++;
riscv_update_subset (&riscv_rps_as, name);
- riscv_reset_subsets_list_arch_str ();
+ riscv_set_arch_str (&riscv_rps_as.subset_list->arch_str);
riscv_set_rvc (false);
if (riscv_subset_supports (&riscv_rps_as, "c")
static void
riscv_write_out_attrs (void)
{
- const char *arch_str, *priv_str, *p;
+ const char *priv_str, *p;
/* versions[0]: major version.
versions[1]: minor version.
versions[2]: revision version. */
unsigned int i;
/* Re-write architecture elf attribute. */
- arch_str = riscv_rps_as.subset_list->arch_str;
- if (!bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str))
+ if (!bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, file_arch_str))
as_fatal (_("error adding attribute: %s"),
bfd_errmsg (bfd_get_error ()));
+ free ((void *) file_arch_str);
/* For the file without any instruction, we don't set the default_priv_spec
according to the privileged elf attributes since the md_assemble isn't
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.
-The complete list of option arguments is shown below:
+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:
@table @code
@item push
+++ /dev/null
-.attribute arch, "rv64ic"
-add a0, a0, a1
-.option push
-.option arch, +d2p0, -c, +xvendor1p0
-add a0, a0, a1
-frcsr a0 # Should add mapping symbol with ISA here, and then dump it to frcsr.
-.option push
-.option arch, +m3p0, +d3p0
-.option pop
-.option pop
+++ /dev/null
-#as: -misa-spec=2.2
-#source: option-arch-01.s
-#objdump: -d
-
-.*:[ ]+file format .*
-
-
-Disassembly of section .text:
-
-0+000 <.text>:
-[ ]+[0-9a-f]+:[ ]+952e[ ]+add[ ]+a0,a0,a1
-[ ]+[0-9a-f]+:[ ]+00b50533[ ]+add[ ]+a0,a0,a1
-[ ]+[0-9a-f]+:[ ]+00302573[ ]+frcsr[ ]+a0
-#...
+++ /dev/null
-#as: -misa-spec=2.2
-#readelf: -A
-#source: option-arch-02.s
-
-Attribute Section: riscv
-File Attributes
- Tag_RISCV_arch: "rv64i2p0_m3p0_f2p0_d3p0_c2p0_zmmul1p0_xvendor32x3p0"
-#...
+++ /dev/null
-.attribute arch, "rv64ic"
-add a0, a0, a1
-.option push
-.option arch, +d2p0, -c, +xvendor1p0
-add a0, a0, a1
-frcsr a0
-.option pop
-.option arch, +m3p0, +d3p0, +xvendor32x3p0
+++ /dev/null
-#as:
-#readelf: -A
-#source: option-arch-03.s
-
-Attribute Section: riscv
-File Attributes
- Tag_RISCV_arch: "rv32i2p1_c2p0"
-#...
+++ /dev/null
-.attribute arch, "rv64ic"
-.option arch, +d2p0, -c
-.option arch, rv32i2p1c2p0
#as: -misa-spec=2.2
+#source: option-arch.s
#readelf: -A
-#source: option-arch-01.s
Attribute Section: riscv
File Attributes
Tag_RISCV_arch: "rv64i2p0_c2p0"
-#...
--- /dev/null
+#as: -misa-spec=2.2
+#source: option-arch.s
+#objdump: -d --syms --special-syms
+
+.*:[ ]+file format .*
+
+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+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+00 l d .riscv.attributes 0+00 .riscv.attributes
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ ]+0:[ ]+952e[ ]+add[ ]+a0,a0,a1
+[ ]+2:[ ]+00b50533[ ]+add[ ]+a0,a0,a1
+[ ]+6:[ ]+00302573[ ]+frcsr[ ]+a0
+[ ]+a:[ ]+952e[ ]+add[ ]+a0,a0,a1
+[ ]+c:[ ]+c8002573[ ]+.insn[ ]+4, 0xc8002573
+#...
--- /dev/null
+.attribute arch, "rv64ic" # file-level, rv64ic
+add a0, a0, a1
+.option push
+.option arch, +d2p0, -c, +xvendor1p0
+add a0, a0, a1 # func-level, rv64i_d2p0_xvendor1p0
+frcsr a0
+.option pop
+.option arch, +m3p0, +d3p0, +xvendor32x3p0
+add a0, a0, a1 # func-level, rv64i_m3p0_d3p0_c_xvendor32x3p0
+.option arch, rv32i2p1c2p0 # FIXME: maybe we should adjust xlen in dis-assembler according to mappin symbols?
+rdcycleh a0 # func-level, rv32i2p1_c2p0