@@ -79,7 +79,10 @@ private:
/* X-len of m_arch. */
unsigned m_xlen;
- riscv_subset_list (const char *, location_t);
+ /* Silent mode, don't emit error if m_silent_p is true. */
+ bool m_silent_p;
+
+ riscv_subset_list (const char *, location_t, bool);
const char *parsing_subset_version (const char *, unsigned *, unsigned *,
unsigned, unsigned, bool, bool *);
@@ -104,7 +107,7 @@ public:
unsigned xlen() const {return m_xlen;};
- static riscv_subset_list *parse (const char *, location_t);
+ static riscv_subset_list *parse (const char *, location_t, bool silent_p);
};
@@ -118,8 +121,11 @@ riscv_subset_t::riscv_subset_t ()
{
}
-riscv_subset_list::riscv_subset_list (const char *arch, location_t loc)
- : m_arch (arch), m_loc (loc), m_head (NULL), m_tail (NULL), m_xlen (0)
+riscv_subset_list::riscv_subset_list (const char *arch,
+ location_t loc,
+ bool silent_p)
+ : m_arch (arch), m_loc (loc), m_head (NULL), m_tail (NULL),
+ m_xlen (0), m_silent_p(silent_p)
{
}
@@ -283,8 +289,9 @@ riscv_subset_list::parsing_subset_version (const char *p,
}
else
{
- error_at (m_loc, "%<-march=%s%>: Expect number "
- "after %<%dp%>.", m_arch, version);
+ if (!m_silent_p)
+ error_at (m_loc, "%<-march=%s%>: Expect number "
+ "after %<%dp%>.", m_arch, version);
return NULL;
}
}
@@ -363,8 +370,9 @@ riscv_subset_list::parse_std_ext (const char *p)
if (m_xlen > 32)
{
- error_at (m_loc, "%<-march=%s%>: rv%de is not a valid base ISA",
- m_arch, m_xlen);
+ if (!m_silent_p)
+ error_at (m_loc, "%<-march=%s%>: rv%de is not a valid base ISA",
+ m_arch, m_xlen);
return NULL;
}
break;
@@ -386,8 +394,9 @@ riscv_subset_list::parse_std_ext (const char *p)
break;
default:
- error_at (m_loc, "%<-march=%s%>: first ISA subset must be %<e%>, "
- "%<i%> or %<g%>", m_arch);
+ if (!m_silent_p)
+ error_at (m_loc, "%<-march=%s%>: first ISA subset must be %<e%>, "
+ "%<i%> or %<g%>", m_arch);
return NULL;
}
@@ -412,13 +421,16 @@ riscv_subset_list::parse_std_ext (const char *p)
if (std_ext != *std_exts)
{
- if (strchr (all_std_exts, std_ext) == NULL)
- error_at (m_loc, "%<-march=%s%>: unsupported ISA subset %<%c%>",
- m_arch, *p);
- else
- error_at (m_loc,
- "%<-march=%s%>: ISA string is not in canonical order. "
- "%<%c%>", m_arch, *p);
+ if (!m_silent_p)
+ {
+ if (strchr (all_std_exts, std_ext) == NULL)
+ error_at (m_loc, "%<-march=%s%>: unsupported ISA subset %<%c%>",
+ m_arch, *p);
+ else
+ error_at (m_loc,
+ "%<-march=%s%>: ISA string is not in canonical order. "
+ "%<%c%>", m_arch, *p);
+ }
return NULL;
}
@@ -522,8 +534,9 @@ riscv_subset_list::parse_multiletter_ext (const char *p,
if (*p != '\0' && *p != '_')
{
- error_at (m_loc, "%<-march=%s%>: %s must separate with _",
- m_arch, ext_type_str);
+ if (!m_silent_p)
+ error_at (m_loc, "%<-march=%s%>: %s must separate with _",
+ m_arch, ext_type_str);
return NULL;
}
}
@@ -534,9 +547,9 @@ riscv_subset_list::parse_multiletter_ext (const char *p,
/* Parsing arch string to subset list, return NULL if parsing failed. */
riscv_subset_list *
-riscv_subset_list::parse (const char *arch, location_t loc)
+riscv_subset_list::parse (const char *arch, location_t loc, bool silent_p)
{
- riscv_subset_list *subset_list = new riscv_subset_list (arch, loc);
+ riscv_subset_list *subset_list = new riscv_subset_list (arch, loc, silent_p);
const char *p = arch;
if (strncmp (p, "rv32", 4) == 0)
{
@@ -550,8 +563,9 @@ riscv_subset_list::parse (const char *arch, location_t loc)
}
else
{
- error_at (loc, "%<-march=%s%>: ISA string must begin with rv32 or rv64",
- arch);
+ if (!silent_p)
+ error_at (loc, "%<-march=%s%>: ISA string must begin with rv32 or rv64",
+ arch);
goto fail;
}
@@ -587,8 +601,9 @@ riscv_subset_list::parse (const char *arch, location_t loc)
if (*p != '\0')
{
- error_at (loc, "%<-march=%s%>: unexpected ISA string at end: %qs",
- arch, p);
+ if (!silent_p)
+ error_at (loc, "%<-march=%s%>: unexpected ISA string at end: %qs",
+ arch, p);
goto fail;
}
@@ -604,18 +619,23 @@ fail:
std::string
riscv_arch_str (bool version_p)
{
- gcc_assert (current_subset_list);
- return current_subset_list->to_string (version_p);
+ if (current_subset_list)
+ return current_subset_list->to_string (version_p);
+ else
+ return std::string();
}
/* Parse a RISC-V ISA string into an option mask. Must clear or set all arch
dependent mask bits, in case more than one -march string is passed. */
static void
-riscv_parse_arch_string (const char *isa, int *flags, location_t loc)
+riscv_parse_arch_string (const char *isa,
+ int *flags,
+ location_t loc,
+ bool silent_p)
{
riscv_subset_list *subset_list;
- subset_list = riscv_subset_list::parse (isa, loc);
+ subset_list = riscv_subset_list::parse (isa, loc, silent_p);
if (!subset_list)
return;
@@ -664,7 +684,7 @@ riscv_handle_option (struct gcc_options *opts,
switch (decoded->opt_index)
{
case OPT_march_:
- riscv_parse_arch_string (decoded->arg, &opts->x_target_flags, loc);
+ riscv_parse_arch_string (decoded->arg, &opts->x_target_flags, loc, false);
return true;
default:
@@ -678,13 +698,67 @@ const char *
riscv_expand_arch (int argc ATTRIBUTE_UNUSED,
const char **argv)
{
- static char *_arch_buf;
gcc_assert (argc == 1);
int flags;
location_t loc = UNKNOWN_LOCATION;
- riscv_parse_arch_string (argv[0], &flags, loc);
- _arch_buf = xstrdup (riscv_arch_str (false).c_str ());
- return _arch_buf;
+ riscv_parse_arch_string (argv[0], &flags, loc, true);
+ const std::string arch = riscv_arch_str (false);
+ if (arch.length())
+ return xasprintf ("-march=%s", arch.c_str());
+ else
+ return "";
+}
+
+/* Return -mabi option string accroding CURRENT_SUBSET_LIST,
+ return empty string if it's NULL.
+
+ Derivative rule:
+ - Using ilp32e E-extension is present.
+ - Using ilp32d or lp64d if D-extension is present.
+ - Otherwise using ilp32 or lp64. */
+
+static const char *
+riscv_get_mabi_from_current_subset_list ()
+{
+ if (current_subset_list == NULL)
+ {
+ return "";
+ }
+
+ if (current_subset_list->xlen() == 32)
+ {
+ /* We don't have ilp32ef or ilp32ed. */
+ if (current_subset_list->lookup ("e"))
+ return "-mabi=ilp32e";
+
+ if (current_subset_list->lookup ("d"))
+ return "-mabi=ilp32d";
+
+ return "-mabi=ilp32";
+ }
+ else
+ {
+ gcc_assert (current_subset_list->xlen() == 64);
+
+ if (current_subset_list->lookup ("d"))
+ return "-mabi=lp64d";
+
+ return "-mabi=lp64";
+ }
+}
+
+/* Derive default -mabi from -march. */
+
+const char *
+riscv_implied_abi_from_arch (int argc, const char **argv)
+{
+ int flags;
+ location_t loc = UNKNOWN_LOCATION;
+
+ gcc_assert (argc == 1);
+
+ riscv_parse_arch_string (argv[0], &flags, loc, true);
+ return riscv_get_mabi_from_current_subset_list ();
}
/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
@@ -41,18 +41,20 @@ along with GCC; see the file COPYING3. If not see
#endif
extern const char *riscv_expand_arch (int argc, const char **argv);
+extern const char *riscv_implied_abi_from_arch (int argc, const char **argv);
# define EXTRA_SPEC_FUNCTIONS \
- { "riscv_expand_arch", riscv_expand_arch },
+ { "riscv_expand_arch", riscv_expand_arch }, \
+ { "riscv_implied_abi_from_arch", riscv_implied_abi_from_arch },
/* Support for a compile-time default CPU, et cetera. The rules are:
--with-arch is ignored if -march is specified.
- --with-abi is ignored if -mabi is specified.
+ --with-abi is ignored if -mabi or -march is specified.
--with-tune is ignored if -mtune is specified. */
#define OPTION_DEFAULT_SPECS \
{"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
{"arch", "%{!march=*:-march=%(VALUE)}" }, \
- {"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \
+ {"abi", "%{!mabi=*:%{!march=*:-mabi=%(VALUE)}}"},
#ifdef IN_LIBGCC2
#undef TARGET_64BIT
@@ -69,8 +71,9 @@ extern const char *riscv_expand_arch (int argc, const char **argv);
%(subtarget_asm_spec)"
#undef DRIVER_SELF_SPECS
-#define DRIVER_SELF_SPECS \
-"%{march=*:-march=%:riscv_expand_arch(%*)}"
+#define DRIVER_SELF_SPECS \
+"%{march=*:%:riscv_expand_arch(%*)}" \
+"%{!mabi=*:%{march=*:%:riscv_implied_abi_from_arch(%*)}}"
#define TARGET_DEFAULT_CMODEL CM_MEDLOW
@@ -25928,7 +25928,14 @@ allows floating-point values up to 32 bits long to be passed in registers; or
@samp{-march=rv64ifd -mabi=lp64}, in which no floating-point arguments will be
passed in registers.
-The default for this argument is system dependent, users who want a specific
+When @option{-mabi=} is not specified, the default value will derived from
+@option{-march=}, the rules is using @samp{d} ABI variant if D extension is
+enabled, otherwise using soft-float ABI variant even F extension is enabled,
+there is an special rule for @samp{rv32e} variant is it always use
+@samp{ilp32e}.
+
+If @option{-march} and @option{-mabi=} both are not specified, the default for
+this argument is system dependent, users who want a specific
calling convention should specify one explicitly. The valid calling
conventions are: @samp{ilp32}, @samp{ilp32f}, @samp{ilp32d}, @samp{lp64},
@samp{lp64f}, and @samp{lp64d}. Some calling conventions are impossible to
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-mabi given" { *-*-* } { "-mabi=*" } } */
+/* { dg-options "-O -march=rv32i" } */
+#if !(defined(__riscv_float_abi_soft) && (__riscv_xlen == 32))
+#error "Should be ilp32"
+#endif
+int main()
+{
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-mabi given" { *-*-* } { "-mabi=*" } } */
+/* { dg-options "-O -march=rv32e" } */
+#if !(defined(__riscv_float_abi_soft) && (__riscv_xlen == 32) && defined(__riscv_abi_rve))
+#error "Should be ilp32e"
+#endif
+int main()
+{
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-mabi given" { *-*-* } { "-mabi=*" } } */
+/* { dg-options "-O -march=rv32if" } */
+#if !(defined(__riscv_float_abi_soft) && (__riscv_xlen == 32))
+#error "Should be ilp32"
+#endif
+int main()
+{
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-mabi given" { *-*-* } { "-mabi=*" } } */
+/* { dg-options "-O -march=rv32ifd" } */
+#if !(defined(__riscv_float_abi_double) && (__riscv_xlen == 32))
+#error "Should be ilp32d"
+#endif
+int main()
+{
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-mabi given" { *-*-* } { "-mabi=*" } } */
+/* { dg-options "-O -march=rv64i" } */
+#if !(defined(__riscv_float_abi_soft) && (__riscv_xlen == 64))
+#error "Should be lp64"
+#endif
+int main()
+{
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-mabi given" { *-*-* } { "-mabi=*" } } */
+/* { dg-options "-O -march=rv64if" } */
+#if !(defined(__riscv_float_abi_soft) && (__riscv_xlen == 64))
+#error "Should be lp64"
+#endif
+int main()
+{
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-mabi given" { *-*-* } { "-mabi=*" } } */
+/* { dg-options "-O -march=rv64ifd" } */
+#if !(defined(__riscv_float_abi_double) && (__riscv_xlen == 64))
+#error "Should be lp64d"
+#endif
+int main()
+{
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-mabi given" { *-*-* } { "-mabi=*" } } */
+/* { dg-options "-O -march=rv64ifd -mabi=lp64" } */
+#if !(defined(__riscv_float_abi_soft) && (__riscv_xlen == 64))
+#error "Should be lp64"
+#endif
+int main()
+{
+ return 0;
+}