@@ -907,7 +907,7 @@ riscv_subset_list::add (const char *subset, bool implied_p)
VERSION_P to determine append version info or not. */
std::string
-riscv_subset_list::to_string (bool version_p) const
+riscv_subset_list::to_string (bool version_p, bool upgrade_exts) const
{
std::ostringstream oss;
oss << "rv" << m_xlen;
@@ -916,6 +916,11 @@ riscv_subset_list::to_string (bool version_p) const
riscv_subset_t *subset;
bool skip_zifencei = false;
+ bool upgrade_zaamo_zalrsc = false;
+ bool has_a_ext = false;
+ bool insert_a_ext = false;
+ bool inserted_a_ext = false;
+ riscv_subset_t *a_subset;
bool skip_zicsr = false;
bool i2p0 = false;
@@ -943,6 +948,31 @@ riscv_subset_list::to_string (bool version_p) const
a mistake in that binutils 2.35 supports zicsr but not zifencei. */
skip_zifencei = true;
#endif
+#ifndef HAVE_AS_MARCH_ZAAMO_ZALRSC
+ /* Upgrade Zaamo/Zalrsc extensions to 'a' since binutils 2.42 and earlier
+ don't recognize zaamo/zalrsc. */
+ upgrade_zaamo_zalrsc = upgrade_exts;
+ if (upgrade_zaamo_zalrsc)
+ {
+ for (subset = m_head; subset != NULL; subset = subset->next)
+ {
+ if (subset->name == "a")
+ has_a_ext = true;
+ if (subset->name == "zaamo" || subset->name == "zalrsc")
+ insert_a_ext = true;
+ }
+ if (insert_a_ext && !has_a_ext)
+ {
+ unsigned int major_version = 0, minor_version = 0;
+ get_default_version ("a", &major_version, &minor_version);
+ a_subset = new riscv_subset_t ();
+ a_subset->name = "a";
+ a_subset->implied_p = false;
+ a_subset->major_version = major_version;
+ a_subset->minor_version = minor_version;
+ }
+ }
+#endif
for (subset = m_head; subset != NULL; subset = subset->next)
{
@@ -954,6 +984,27 @@ riscv_subset_list::to_string (bool version_p) const
subset->name == "zicsr")
continue;
+ if (upgrade_zaamo_zalrsc && subset->name == "zaamo")
+ continue;
+
+ if (upgrade_zaamo_zalrsc && subset->name == "zalrsc")
+ continue;
+
+ if (upgrade_zaamo_zalrsc && insert_a_ext && !has_a_ext && !inserted_a_ext)
+ {
+ gcc_assert (a_subset);
+ /* Insert `a` extension in cannonical order. */
+ if (subset_cmp (a_subset->name, subset->name) > 0)
+ {
+ oss << a_subset->name;
+ if (version_p)
+ oss << a_subset->major_version
+ << 'p'
+ << a_subset->minor_version;
+ inserted_a_ext = true;
+ }
+ }
+
/* For !version_p, we only separate extension with underline for
multi-letter extension. */
if (!first &&
@@ -973,6 +1024,12 @@ riscv_subset_list::to_string (bool version_p) const
<< subset->minor_version;
}
+ if (upgrade_zaamo_zalrsc && insert_a_ext && !has_a_ext)
+ {
+ gcc_assert (inserted_a_ext);
+ free (a_subset);
+ }
+
return oss.str ();
}
@@ -1587,10 +1644,10 @@ riscv_subset_list::finalize ()
/* Return the current arch string. */
std::string
-riscv_arch_str (bool version_p)
+riscv_arch_str (bool version_p, bool upgrade_exts)
{
if (current_subset_list)
- return current_subset_list->to_string (version_p);
+ return current_subset_list->to_string (version_p, upgrade_exts);
else
return std::string();
}
@@ -1896,18 +1953,33 @@ riscv_handle_option (struct gcc_options *opts,
const char *
riscv_expand_arch (int argc ATTRIBUTE_UNUSED,
- const char **argv)
+ const char **argv,
+ bool upgrade_exts)
{
gcc_assert (argc == 1);
location_t loc = UNKNOWN_LOCATION;
riscv_parse_arch_string (argv[0], NULL, loc);
- const std::string arch = riscv_arch_str (false);
+ const std::string arch = riscv_arch_str (/*version_p*/ false, upgrade_exts);
if (arch.length())
return xasprintf ("-march=%s", arch.c_str());
else
return "";
}
+const char *
+riscv_expand_arch_upgrade_exts (int argc ATTRIBUTE_UNUSED,
+ const char **argv)
+{
+ return riscv_expand_arch (argc, argv, /*upgrade_exts*/ true);
+}
+
+const char *
+riscv_expand_arch_no_upgrade_exts (int argc ATTRIBUTE_UNUSED,
+ const char **argv)
+{
+ return riscv_expand_arch (argc, argv, /*upgrade_exts*/ false);
+}
+
/* Expand default -mtune option from -mcpu option, use default --with-tune value
if -mcpu don't have valid value. */
@@ -1927,7 +1999,8 @@ riscv_default_mtune (int argc, const char **argv)
const char *
riscv_expand_arch_from_cpu (int argc ATTRIBUTE_UNUSED,
- const char **argv)
+ const char **argv,
+ bool upgrade_exts)
{
gcc_assert (argc > 0 && argc <= 2);
const char *default_arch_str = NULL;
@@ -1950,10 +2023,24 @@ riscv_expand_arch_from_cpu (int argc ATTRIBUTE_UNUSED,
location_t loc = UNKNOWN_LOCATION;
riscv_parse_arch_string (arch_str, NULL, loc);
- const std::string arch = riscv_arch_str (false);
+ const std::string arch = riscv_arch_str (/*version_p*/ false, upgrade_exts);
return xasprintf ("-march=%s", arch.c_str());
}
+const char *
+riscv_expand_arch_from_cpu_upgrade_exts (int argc ATTRIBUTE_UNUSED,
+ const char **argv)
+{
+ return riscv_expand_arch_from_cpu (argc, argv, /*upgrade_exts*/ true);
+}
+
+const char *
+riscv_expand_arch_from_cpu_no_upgrade_exts (int argc ATTRIBUTE_UNUSED,
+ const char **argv)
+{
+ return riscv_expand_arch_from_cpu (argc, argv, /*upgrade_exts*/ false);
+}
+
/* Report error if not found suitable multilib. */
const char *
riscv_multi_lib_check (int argc ATTRIBUTE_UNUSED,
@@ -629,6 +629,12 @@
#endif
+/* Define if the assembler understands -march=rv*_zaamo_zalrsc. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_MARCH_ZAAMO_ZALRSC
+#endif
+
+
/* Define if the assembler understands -march=rv*_zifencei. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_MARCH_ZIFENCEI
@@ -183,7 +183,8 @@ extern tree riscv_builtin_decl (unsigned int, bool);
extern void riscv_init_builtins (void);
/* Routines implemented in riscv-common.cc. */
-extern std::string riscv_arch_str (bool version_p = true);
+extern std::string riscv_arch_str (bool version_p = true,
+ bool upgrade_exts = false);
extern void riscv_parse_arch_string (const char *, struct gcc_options *, location_t);
extern bool riscv_hard_regno_rename_ok (unsigned, unsigned);
@@ -90,7 +90,7 @@ public:
int major_version = RISCV_DONT_CARE_VERSION,
int minor_version = RISCV_DONT_CARE_VERSION) const;
- std::string to_string (bool) const;
+ std::string to_string (bool, bool) const;
unsigned xlen () const {return m_xlen;};
@@ -367,7 +367,9 @@ riscv_process_target_attr (tree fndecl, tree args, location_t loc,
/* Add the string of the target attribute to the fndecl hash table. */
riscv_subset_list *subset_list = attr_parser.get_riscv_subset_list ();
if (subset_list)
- riscv_func_target_put (fndecl, subset_list->to_string (true));
+ riscv_func_target_put (fndecl,
+ subset_list->to_string (/*version_p*/ true,
+ /*upgrade_exts*/ true));
return true;
}
@@ -9425,8 +9425,10 @@ riscv_sched_adjust_cost (rtx_insn *, int, rtx_insn *insn, int cost,
static void
riscv_emit_attribute ()
{
+ /* Upgrade extensions if necessary for the assember to understand
+ Eg. Zalrsc -> a. */
fprintf (asm_out_file, "\t.attribute arch, \"%s\"\n",
- riscv_arch_str ().c_str ());
+ riscv_arch_str (/*version_p*/ true, /*upgrade_exts*/ true).c_str ());
fprintf (asm_out_file, "\t.attribute unaligned_access, %d\n",
TARGET_STRICT_ALIGN ? 0 : 1);
@@ -9468,7 +9470,8 @@ riscv_declare_function_name (FILE *stream, const char *name, tree fndecl)
std::string *target_name = riscv_func_target_get (fndecl);
std::string isa = target_name != NULL
? *target_name
- : riscv_cmdline_subset_list ()->to_string (true);
+ : riscv_cmdline_subset_list ()->to_string (/*version_p*/ true,
+ /*upgrade_exts*/ true);
fprintf (stream, "\t.option arch, %s\n", isa.c_str ());
riscv_func_target_remove_and_destory (fndecl);
@@ -46,17 +46,24 @@ along with GCC; see the file COPYING3. If not see
#define RISCV_TUNE_STRING_DEFAULT "rocket"
#endif
-extern const char *riscv_expand_arch (int argc, const char **argv);
-extern const char *riscv_expand_arch_from_cpu (int argc, const char **argv);
+extern const char *riscv_expand_arch_upgrade_exts (int argc, const char **argv);
+extern const char *riscv_expand_arch_no_upgrade_exts (int argc,
+ const char **argv);
+extern const char *riscv_expand_arch_from_cpu_upgrade_exts (int argc,
+ const char **argv);
+extern const char *riscv_expand_arch_from_cpu_no_upgrade_exts (int argc,
+ const char **argv);
extern const char *riscv_default_mtune (int argc, const char **argv);
extern const char *riscv_multi_lib_check (int argc, const char **argv);
extern const char *riscv_arch_help (int argc, const char **argv);
-# define EXTRA_SPEC_FUNCTIONS \
- { "riscv_expand_arch", riscv_expand_arch }, \
- { "riscv_expand_arch_from_cpu", riscv_expand_arch_from_cpu }, \
- { "riscv_default_mtune", riscv_default_mtune }, \
- { "riscv_multi_lib_check", riscv_multi_lib_check }, \
+# define EXTRA_SPEC_FUNCTIONS \
+ { "riscv_expand_arch_u", riscv_expand_arch_upgrade_exts }, \
+ { "riscv_expand_arch_nu", riscv_expand_arch_no_upgrade_exts }, \
+ { "riscv_expand_arch_from_cpu_nu", riscv_expand_arch_from_cpu_no_upgrade_exts }, \
+ { "riscv_expand_arch_from_cpu_u", riscv_expand_arch_from_cpu_upgrade_exts }, \
+ { "riscv_default_mtune", riscv_default_mtune }, \
+ { "riscv_multi_lib_check", riscv_multi_lib_check }, \
{ "riscv_arch_help", riscv_arch_help },
/* Support for a compile-time default CPU, et cetera. The rules are:
@@ -68,15 +75,15 @@ extern const char *riscv_arch_help (int argc, const char **argv);
But using default -march/-mtune value if -mcpu don't have valid option. */
#define OPTION_DEFAULT_SPECS \
- {"tune", "%{!mtune=*:" \
- " %{!mcpu=*:-mtune=%(VALUE)}" \
- " %{mcpu=*:-mtune=%:riscv_default_mtune(%* %(VALUE))}}" }, \
- {"arch", "%{!march=*:" \
- " %{!mcpu=*:-march=%(VALUE)}" \
- " %{mcpu=*:%:riscv_expand_arch_from_cpu(%* %(VALUE))}}" }, \
- {"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \
- {"isa_spec", "%{!misa-spec=*:-misa-spec=%(VALUE)}" }, \
- {"tls", "%{!mtls-dialect=*:-mtls-dialect=%(VALUE)}"}, \
+ {"tune", "%{!mtune=*:" \
+ " %{!mcpu=*:-mtune=%(VALUE)}" \
+ " %{mcpu=*:-mtune=%:riscv_default_mtune(%* %(VALUE))}}" }, \
+ {"arch", "%{!march=*:" \
+ " %{!mcpu=*:-march=%(VALUE)}" \
+ " %{mcpu=*:%:riscv_expand_arch_from_cpu_nu(%* %(VALUE))}}" }, \
+ {"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \
+ {"isa_spec", "%{!misa-spec=*:-misa-spec=%(VALUE)}" }, \
+ {"tls", "%{!mtls-dialect=*:-mtls-dialect=%(VALUE)}"}, \
#ifdef IN_LIBGCC2
#undef TARGET_64BIT
@@ -103,7 +110,8 @@ extern const char *riscv_arch_help (int argc, const char **argv);
#define ASM_SPEC "\
%(subtarget_asm_debugging_spec) \
%{" FPIE_OR_FPIC_SPEC ":-fpic} \
-%{march=*} \
+%{march=*:%:riscv_expand_arch_u(%*)} \
+%{!march=*:%{mcpu=*:%:riscv_expand_arch_from_cpu_u(%*)}} \
%{mabi=*} \
%{mno-relax} \
%{mbig-endian} \
@@ -116,8 +124,8 @@ ASM_MISA_SPEC
"%{march=help:%:riscv_arch_help()} " \
"%{print-supported-extensions:%:riscv_arch_help()} " \
"%{-print-supported-extensions:%:riscv_arch_help()} " \
-"%{march=*:%:riscv_expand_arch(%*)} " \
-"%{!march=*:%{mcpu=*:%:riscv_expand_arch_from_cpu(%*)}} "
+"%{march=*:%:riscv_expand_arch_nu(%*)} " \
+"%{!march=*:%{mcpu=*:%:riscv_expand_arch_from_cpu_nu(%*)}} "
#define TARGET_DEFAULT_CMODEL CM_MEDLOW
@@ -30820,6 +30820,37 @@ if test $gcc_cv_as_riscv_march_zifencei = yes; then
$as_echo "#define HAVE_AS_MARCH_ZIFENCEI 1" >>confdefs.h
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for -march=rv32i_zaamo_zalrsc support" >&5
+$as_echo_n "checking assembler for -march=rv32i_zaamo_zalrsc support... " >&6; }
+if ${gcc_cv_as_riscv_march_zaamo_zalrsc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcc_cv_as_riscv_march_zaamo_zalrsc=no
+ if test x$gcc_cv_as != x; then
+ $as_echo '' > conftest.s
+ if { ac_try='$gcc_cv_as $gcc_cv_as_flags -march=rv32i_zaamo_zalrsc -o conftest.o conftest.s >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ gcc_cv_as_riscv_march_zaamo_zalrsc=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_riscv_march_zaamo_zalrsc" >&5
+$as_echo "$gcc_cv_as_riscv_march_zaamo_zalrsc" >&6; }
+if test $gcc_cv_as_riscv_march_zaamo_zalrsc = yes; then
+
+$as_echo "#define HAVE_AS_MARCH_ZAAMO_ZALRSC 1" >>confdefs.h
+
fi
;;
@@ -5452,6 +5452,11 @@ configured with --enable-newlib-nano-formatted-io.])
[-march=rv32i_zifencei2p0],,,
[AC_DEFINE(HAVE_AS_MARCH_ZIFENCEI, 1,
[Define if the assembler understands -march=rv*_zifencei.])])
+ gcc_GAS_CHECK_FEATURE([-march=rv32i_zaamo_zalrsc support],
+ gcc_cv_as_riscv_march_zaamo_zalrsc,
+ [-march=rv32i_zaamo_zalrsc],,,
+ [AC_DEFINE(HAVE_AS_MARCH_ZAAMO_ZALRSC, 1,
+ [Define if the assembler understands -march=rv*_zaamo_zalrsc.])])
;;
loongarch*-*-*)
gcc_GAS_CHECK_FEATURE([.dtprelword support],
Binutils 2.42 and before don't support Zaamo/Zalrsc. Add a configure check to upgrade Zaamo/Zalrsc to 'a' when the assember does not support it. This change respects Zaamo/Zalrsc when generating code. Testcases that check for the default isa string will fail with the old binutils since zaamo/zalrsc aren't emitted anymore. All other Zaamo/Zalrsc testcases pass. gcc/ChangeLog: * common/config/riscv/riscv-common.cc (riscv_subset_list::to_string): Add toggle to promote Zaamo/Zalrsc extensions to 'a'. (riscv_arch_str): Ditto. (riscv_expand_arch): Ditto. (riscv_expand_arch_from_cpu): Ditto. (riscv_expand_arch_upgrade_exts): New function. Wrapper around riscv_expand_arch to preserve the function signature. (riscv_expand_arch_no_upgrade_exts): Ditto (riscv_expand_arch_from_cpu_upgrade_exts): New function. Wrapper around riscv_expand_arch_from_cpu to preserve the function signature. (riscv_expand_arch_from_cpu_no_upgrade_exts): Ditto. * config/riscv/riscv-protos.h (riscv_arch_str): Add toggle to function prototype. * config/riscv/riscv-subset.h: Ditto. * config/riscv/riscv-target-attr.cc (riscv_process_target_attr): * config/riscv/riscv.cc (riscv_emit_attribute): (riscv_declare_function_name): * config/riscv/riscv.h (riscv_expand_arch): Remove. (riscv_expand_arch_from_cpu): Ditto. (riscv_expand_arch_upgrade_exts): Add toggle wrapper functions. (riscv_expand_arch_no_upgrade_exts): Ditto. (riscv_expand_arch_from_cpu_upgrade_exts): Ditto. (riscv_expand_arch_from_cpu_no_upgrade_exts): Ditto. (EXTRA_SPEC_FUNCTIONS): Ditto. (OPTION_DEFAULT_SPECS): Use non-upgraded march string when invoking the compiler. (ASM_SPEC): Use upgraded march string when invoking the assembler. * config.in: Regenerate. * configure: Regenerate. * configure.ac: Add zaamo/zalrsc assembler check. Signed-off-by: Patrick O'Neill <patrick@rivosinc.com> --- This change is way more invasive than the last one hence the RFC. I'd be happy to iterate more on this or just commit v1 with the misc configure diffs removed. --- gcc/common/config/riscv/riscv-common.cc | 101 ++++++++++++++++++++++-- gcc/config.in | 6 ++ gcc/config/riscv/riscv-protos.h | 3 +- gcc/config/riscv/riscv-subset.h | 2 +- gcc/config/riscv/riscv-target-attr.cc | 4 +- gcc/config/riscv/riscv.cc | 7 +- gcc/config/riscv/riscv.h | 46 ++++++----- gcc/configure | 31 ++++++++ gcc/configure.ac | 5 ++ 9 files changed, 174 insertions(+), 31 deletions(-) -- 2.34.1