Commit f9a8ca4c by Kito Cheng

RISC-V: Handle implied extension for -march parser.

  - Implied rule are introduced into latest RISC-V ISA spec.

  - Only implemented D implied F-extension. Zicsr and Zifence are not
    implement yet, so the rule not included in this patch.

  - Pass preprocessed arch string to arch.

  - Verified with binutils 2.30 and 2.34.

gcc/ChangeLog

	* common/config/riscv/riscv-common.c (riscv_implied_info_t): New.
	(riscv_implied_info): New.
	(riscv_subset_list): Add handle_implied_ext.
	(riscv_subset_list::to_string): New parameter version_p to
	control output format.
	(riscv_subset_list::handle_implied_ext): New.
	(riscv_subset_list::parse_std_ext): Call handle_implied_ext.
	(riscv_arch_str): New parameter version_p to control output format.
	(riscv_expand_arch): New.
	* config/riscv/riscv-protos.h (riscv_arch_str): New parameter,
	version_p.
	* config/riscv/riscv.h (riscv_expand_arch): New,
	(EXTRA_SPEC_FUNCTIONS): Define.
	(ASM_SPEC): Transform -march= via riscv_expand_arch.

gcc/testsuite/ChangeLog

	* gcc.target/riscv/arch-6.c: New.
	* gcc.target/riscv/attribute-11.c: New.
	* gcc.target/riscv/attribute-12.c: New.
parent e674ee15
...@@ -44,6 +44,20 @@ struct riscv_subset_t ...@@ -44,6 +44,20 @@ struct riscv_subset_t
struct riscv_subset_t *next; struct riscv_subset_t *next;
}; };
/* Type for implied ISA info. */
struct riscv_implied_info_t
{
const char *ext;
const char *implied_ext;
};
/* Implied ISA info, must end with NULL sentinel. */
riscv_implied_info_t riscv_implied_info[] =
{
{"d", "f"},
{NULL, NULL}
};
/* Subset list. */ /* Subset list. */
class riscv_subset_list class riscv_subset_list
{ {
...@@ -73,6 +87,8 @@ private: ...@@ -73,6 +87,8 @@ private:
const char *parse_multiletter_ext (const char *, const char *, const char *parse_multiletter_ext (const char *, const char *,
const char *); const char *);
void handle_implied_ext (const char *, int, int);
public: public:
~riscv_subset_list (); ~riscv_subset_list ();
...@@ -82,7 +98,7 @@ public: ...@@ -82,7 +98,7 @@ public:
int major_version = RISCV_DONT_CARE_VERSION, int major_version = RISCV_DONT_CARE_VERSION,
int minor_version = RISCV_DONT_CARE_VERSION) const; int minor_version = RISCV_DONT_CARE_VERSION) const;
std::string to_string () const; std::string to_string (bool) const;
unsigned xlen() const {return m_xlen;}; unsigned xlen() const {return m_xlen;};
...@@ -140,10 +156,11 @@ riscv_subset_list::add (const char *subset, int major_version, ...@@ -140,10 +156,11 @@ riscv_subset_list::add (const char *subset, int major_version,
m_tail = s; m_tail = s;
} }
/* Convert subset info to string with explicit version info. */ /* Convert subset info to string with explicit version info,
VERSION_P to determine append version info or not. */
std::string std::string
riscv_subset_list::to_string () const riscv_subset_list::to_string (bool version_p) const
{ {
std::ostringstream oss; std::ostringstream oss;
oss << "rv" << m_xlen; oss << "rv" << m_xlen;
...@@ -153,14 +170,20 @@ riscv_subset_list::to_string () const ...@@ -153,14 +170,20 @@ riscv_subset_list::to_string () const
while (subset != NULL) while (subset != NULL)
{ {
if (!first) /* For !version_p, we only separate extension with underline for
multi-letter extension. */
if (!first &&
(version_p || subset->name.length() > 1))
oss << '_'; oss << '_';
first = false; first = false;
oss << subset->name oss << subset->name;
<< subset->major_version
<< 'p' if (version_p)
<< subset->minor_version; oss << subset->major_version
<< 'p'
<< subset->minor_version;
subset = subset->next; subset = subset->next;
} }
...@@ -394,11 +417,38 @@ riscv_subset_list::parse_std_ext (const char *p) ...@@ -394,11 +417,38 @@ riscv_subset_list::parse_std_ext (const char *p)
subset[0] = std_ext; subset[0] = std_ext;
handle_implied_ext (subset, major_version, minor_version);
add (subset, major_version, minor_version); add (subset, major_version, minor_version);
} }
return p; return p;
} }
/* Check any implied extensions for EXT with version
MAJOR_VERSION.MINOR_VERSION. */
void
riscv_subset_list::handle_implied_ext (const char *ext,
int major_version,
int minor_version)
{
riscv_implied_info_t *implied_info;
for (implied_info = &riscv_implied_info[0];
implied_info->ext;
++implied_info)
{
if (strcmp (ext, implied_info->ext) != 0)
continue;
/* Skip if implied extension already present. */
if (lookup (implied_info->implied_ext))
continue;
/* TODO: Implied extension might use different version. */
add (implied_info->implied_ext, major_version, minor_version);
}
}
/* Parsing function for multi-letter extensions. /* Parsing function for multi-letter extensions.
Return Value: Return Value:
...@@ -530,10 +580,10 @@ fail: ...@@ -530,10 +580,10 @@ fail:
/* Return the current arch string. */ /* Return the current arch string. */
std::string std::string
riscv_arch_str () riscv_arch_str (bool version_p)
{ {
gcc_assert (current_subset_list); gcc_assert (current_subset_list);
return current_subset_list->to_string (); return current_subset_list->to_string (version_p);
} }
/* Parse a RISC-V ISA string into an option mask. Must clear or set all arch /* Parse a RISC-V ISA string into an option mask. Must clear or set all arch
...@@ -600,6 +650,21 @@ riscv_handle_option (struct gcc_options *opts, ...@@ -600,6 +650,21 @@ riscv_handle_option (struct gcc_options *opts,
} }
} }
/* Expand arch string with implied extensions. */
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;
}
/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
static const struct default_options riscv_option_optimization_table[] = static const struct default_options riscv_option_optimization_table[] =
{ {
......
...@@ -88,7 +88,7 @@ extern tree riscv_builtin_decl (unsigned int, bool); ...@@ -88,7 +88,7 @@ extern tree riscv_builtin_decl (unsigned int, bool);
extern void riscv_init_builtins (void); extern void riscv_init_builtins (void);
/* Routines implemented in riscv-common.c. */ /* Routines implemented in riscv-common.c. */
extern std::string riscv_arch_str (); extern std::string riscv_arch_str (bool version_p = true);
extern bool riscv_hard_regno_rename_ok (unsigned, unsigned); extern bool riscv_hard_regno_rename_ok (unsigned, unsigned);
......
...@@ -40,6 +40,11 @@ along with GCC; see the file COPYING3. If not see ...@@ -40,6 +40,11 @@ along with GCC; see the file COPYING3. If not see
#define RISCV_TUNE_STRING_DEFAULT "rocket" #define RISCV_TUNE_STRING_DEFAULT "rocket"
#endif #endif
extern const char *riscv_expand_arch (int argc, const char **argv);
# define EXTRA_SPEC_FUNCTIONS \
{ "riscv_expand_arch", riscv_expand_arch },
/* Support for a compile-time default CPU, et cetera. The rules are: /* Support for a compile-time default CPU, et cetera. The rules are:
--with-arch is ignored if -march is specified. --with-arch is ignored if -march is specified.
--with-abi is ignored if -mabi is specified. --with-abi is ignored if -mabi is specified.
...@@ -59,7 +64,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -59,7 +64,7 @@ along with GCC; see the file COPYING3. If not see
#define ASM_SPEC "\ #define ASM_SPEC "\
%(subtarget_asm_debugging_spec) \ %(subtarget_asm_debugging_spec) \
%{" FPIE_OR_FPIC_SPEC ":-fpic} \ %{" FPIE_OR_FPIC_SPEC ":-fpic} \
%{march=*} \ %{march=*:-march=%:riscv_expand_arch(%*)} \
%{mabi=*} \ %{mabi=*} \
%(subtarget_asm_spec)" %(subtarget_asm_spec)"
......
/* { dg-do compile } */
/* { dg-options "-O -march=rv32id -mabi=ilp32" } */
int foo()
{
}
/* { dg-do compile } */
/* { dg-options "-O -mriscv-attribute -march=rv32id -mabi=ilp32" } */
int foo()
{
}
/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_f2p0_d2p0\"" } } */
/* { dg-do compile } */
/* { dg-options "-O -mriscv-attribute -march=rv32ifd -mabi=ilp32" } */
int foo()
{
}
/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_f2p0_d2p0\"" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment