[PATCH] RISC-V: Derive ABI from -march if -mabi is not present.
Kito Cheng
kito.cheng@sifive.com
Tue Oct 6 06:22:01 GMT 2020
Hi Jim, Palmer and Andrew:
I think this patch is kind of major change for GCC RISC-V port, so I cc all
RISC-V gcc maintainer to make sure this change is fine with you guys.
- Motivation of this patch:
1. Sync behavior between clang/llvm.
2. Preparation for -mcpu option support, -mcpu will set -march
according the core default arch, however it would be awkward
if we only change arch: user need to know the default arch of
the core and then set the right ABI, of cause user still can
specify arch and abi via -march and -mabi.
- This patch has change the behavior for default value of ABI, the ABI
will derive from -march if -mabi is not given, which is same behavior
as clang/llvm.
- So the new rule for the ABI:
- Use value from -mabi if the option is present.
- Derive ABI from -march if -mabi is not present.
- Using default value from `--with-abi` if -mabi and -march are both not
present.
- Derivative rule:
- Using ilp32e E-extension is present.
- Using ilp32d or lp64d if D-extension is present.
- Otherwise using ilp32 or lp64.
gcc/ChangeLog:
* common/config/riscv/riscv-common.c:
* config/riscv/riscv.h:
* doc/invoke.texi
gcc/testsuite/ChangeLog:
* gcc.target/riscv/implied-abi-1.c: New.
* gcc.target/riscv/implied-abi-2.c: Ditto.
* gcc.target/riscv/implied-abi-3.c: Ditto.
* gcc.target/riscv/implied-abi-4.c: Ditto.
* gcc.target/riscv/implied-abi-5.c: Ditto.
* gcc.target/riscv/implied-abi-6.c: Ditto.
* gcc.target/riscv/implied-abi-7.c: Ditto.
* gcc.target/riscv/implied-abi-8.c: Ditto.
---
gcc/common/config/riscv/riscv-common.c | 142 +++++++++++++-----
gcc/config/riscv/riscv.h | 13 +-
gcc/doc/invoke.texi | 9 +-
.../gcc.target/riscv/implied-abi-1.c | 10 ++
.../gcc.target/riscv/implied-abi-2.c | 10 ++
.../gcc.target/riscv/implied-abi-3.c | 10 ++
.../gcc.target/riscv/implied-abi-4.c | 10 ++
.../gcc.target/riscv/implied-abi-5.c | 10 ++
.../gcc.target/riscv/implied-abi-6.c | 10 ++
.../gcc.target/riscv/implied-abi-7.c | 10 ++
.../gcc.target/riscv/implied-abi-8.c | 10 ++
11 files changed, 204 insertions(+), 40 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/implied-abi-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/implied-abi-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/implied-abi-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/implied-abi-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/implied-abi-5.c
create mode 100644 gcc/testsuite/gcc.target/riscv/implied-abi-6.c
create mode 100644 gcc/testsuite/gcc.target/riscv/implied-abi-7.c
create mode 100644 gcc/testsuite/gcc.target/riscv/implied-abi-8.c
diff --git a/gcc/common/config/riscv/riscv-common.c b/gcc/common/config/riscv/riscv-common.c
index 82c5154b6118..07afc1a365e3 100644
--- a/gcc/common/config/riscv/riscv-common.c
+++ b/gcc/common/config/riscv/riscv-common.c
@@ -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. */
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index b7b4a1c88a52..0c37dbd6f877 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -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
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index f623467b7637..c6ba738aa0b7 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -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
diff --git a/gcc/testsuite/gcc.target/riscv/implied-abi-1.c b/gcc/testsuite/gcc.target/riscv/implied-abi-1.c
new file mode 100644
index 000000000000..0ed81d75fadc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/implied-abi-1.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/implied-abi-2.c b/gcc/testsuite/gcc.target/riscv/implied-abi-2.c
new file mode 100644
index 000000000000..493990b1cadf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/implied-abi-2.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/implied-abi-3.c b/gcc/testsuite/gcc.target/riscv/implied-abi-3.c
new file mode 100644
index 000000000000..09d64793c4e6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/implied-abi-3.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/implied-abi-4.c b/gcc/testsuite/gcc.target/riscv/implied-abi-4.c
new file mode 100644
index 000000000000..432e5646d098
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/implied-abi-4.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/implied-abi-5.c b/gcc/testsuite/gcc.target/riscv/implied-abi-5.c
new file mode 100644
index 000000000000..45e64e91e845
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/implied-abi-5.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/implied-abi-6.c b/gcc/testsuite/gcc.target/riscv/implied-abi-6.c
new file mode 100644
index 000000000000..7fe29c6206ca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/implied-abi-6.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/implied-abi-7.c b/gcc/testsuite/gcc.target/riscv/implied-abi-7.c
new file mode 100644
index 000000000000..bb334f5f36cf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/implied-abi-7.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/implied-abi-8.c b/gcc/testsuite/gcc.target/riscv/implied-abi-8.c
new file mode 100644
index 000000000000..a48a47366978
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/implied-abi-8.c
@@ -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;
+}
--
2.28.0
More information about the Gcc-patches
mailing list