1 /* Common hooks for RISC-V.
2 Copyright (C) 2016-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
23 #define INCLUDE_STRING
26 #include "coretypes.h"
28 #include "common/common-target.h"
29 #include "common/common-target-def.h"
32 #include "diagnostic-core.h"
33 #include "config/riscv/riscv-protos.h"
34 #include "config/riscv/riscv-subset.h"
36 #ifdef TARGET_BIG_ENDIAN_DEFAULT
37 #undef TARGET_DEFAULT_TARGET_FLAGS
38 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
41 /* Type for implied ISA info. */
42 struct riscv_implied_info_t
45 const char *implied_ext;
48 /* Implied ISA info, must end with NULL sentinel. */
49 static const riscv_implied_info_t riscv_implied_info[] =
94 {"zvl128b", "zvl64b"},
95 {"zvl256b", "zvl128b"},
96 {"zvl512b", "zvl256b"},
97 {"zvl1024b", "zvl512b"},
98 {"zvl2048b", "zvl1024b"},
99 {"zvl4096b", "zvl2048b"},
100 {"zvl8192b", "zvl4096b"},
101 {"zvl16384b", "zvl8192b"},
102 {"zvl32768b", "zvl16384b"},
103 {"zvl65536b", "zvl32768b"},
108 {"zhinx", "zhinxmin"},
109 {"zhinxmin", "zfinx"},
114 /* This structure holds version information for specific ISA version. */
116 struct riscv_ext_version
119 enum riscv_isa_spec_class isa_spec_class;
124 /* All standard extensions defined in all supported ISA spec. */
125 static const struct riscv_ext_version riscv_ext_version_table[] =
127 /* name, ISA spec, major version, minor_version. */
128 {"e", ISA_SPEC_CLASS_20191213, 1, 9},
129 {"e", ISA_SPEC_CLASS_20190608, 1, 9},
130 {"e", ISA_SPEC_CLASS_2P2, 1, 9},
132 {"i", ISA_SPEC_CLASS_20191213, 2, 1},
133 {"i", ISA_SPEC_CLASS_20190608, 2, 1},
134 {"i", ISA_SPEC_CLASS_2P2, 2, 0},
136 {"m", ISA_SPEC_CLASS_20191213, 2, 0},
137 {"m", ISA_SPEC_CLASS_20190608, 2, 0},
138 {"m", ISA_SPEC_CLASS_2P2, 2, 0},
140 {"a", ISA_SPEC_CLASS_20191213, 2, 1},
141 {"a", ISA_SPEC_CLASS_20190608, 2, 0},
142 {"a", ISA_SPEC_CLASS_2P2, 2, 0},
144 {"f", ISA_SPEC_CLASS_20191213, 2, 2},
145 {"f", ISA_SPEC_CLASS_20190608, 2, 2},
146 {"f", ISA_SPEC_CLASS_2P2, 2, 0},
148 {"d", ISA_SPEC_CLASS_20191213, 2, 2},
149 {"d", ISA_SPEC_CLASS_20190608, 2, 2},
150 {"d", ISA_SPEC_CLASS_2P2, 2, 0},
152 {"c", ISA_SPEC_CLASS_20191213, 2, 0},
153 {"c", ISA_SPEC_CLASS_20190608, 2, 0},
154 {"c", ISA_SPEC_CLASS_2P2, 2, 0},
156 {"h", ISA_SPEC_CLASS_NONE, 1, 0},
158 {"v", ISA_SPEC_CLASS_NONE, 1, 0},
160 {"zicsr", ISA_SPEC_CLASS_20191213, 2, 0},
161 {"zicsr", ISA_SPEC_CLASS_20190608, 2, 0},
163 {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0},
164 {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0},
166 {"zawrs", ISA_SPEC_CLASS_NONE, 1, 0},
168 {"zba", ISA_SPEC_CLASS_NONE, 1, 0},
169 {"zbb", ISA_SPEC_CLASS_NONE, 1, 0},
170 {"zbc", ISA_SPEC_CLASS_NONE, 1, 0},
171 {"zbs", ISA_SPEC_CLASS_NONE, 1, 0},
173 {"zfinx", ISA_SPEC_CLASS_NONE, 1, 0},
174 {"zdinx", ISA_SPEC_CLASS_NONE, 1, 0},
175 {"zhinx", ISA_SPEC_CLASS_NONE, 1, 0},
176 {"zhinxmin", ISA_SPEC_CLASS_NONE, 1, 0},
178 {"zbkb", ISA_SPEC_CLASS_NONE, 1, 0},
179 {"zbkc", ISA_SPEC_CLASS_NONE, 1, 0},
180 {"zbkx", ISA_SPEC_CLASS_NONE, 1, 0},
181 {"zkne", ISA_SPEC_CLASS_NONE, 1, 0},
182 {"zknd", ISA_SPEC_CLASS_NONE, 1, 0},
183 {"zknh", ISA_SPEC_CLASS_NONE, 1, 0},
184 {"zkr", ISA_SPEC_CLASS_NONE, 1, 0},
185 {"zksed", ISA_SPEC_CLASS_NONE, 1, 0},
186 {"zksh", ISA_SPEC_CLASS_NONE, 1, 0},
187 {"zkt", ISA_SPEC_CLASS_NONE, 1, 0},
189 {"zicboz",ISA_SPEC_CLASS_NONE, 1, 0},
190 {"zicbom",ISA_SPEC_CLASS_NONE, 1, 0},
191 {"zicbop",ISA_SPEC_CLASS_NONE, 1, 0},
193 {"zk", ISA_SPEC_CLASS_NONE, 1, 0},
194 {"zkn", ISA_SPEC_CLASS_NONE, 1, 0},
195 {"zks", ISA_SPEC_CLASS_NONE, 1, 0},
197 {"zve32x", ISA_SPEC_CLASS_NONE, 1, 0},
198 {"zve32f", ISA_SPEC_CLASS_NONE, 1, 0},
199 {"zve32d", ISA_SPEC_CLASS_NONE, 1, 0},
200 {"zve64x", ISA_SPEC_CLASS_NONE, 1, 0},
201 {"zve64f", ISA_SPEC_CLASS_NONE, 1, 0},
202 {"zve64d", ISA_SPEC_CLASS_NONE, 1, 0},
204 {"zvl32b", ISA_SPEC_CLASS_NONE, 1, 0},
205 {"zvl64b", ISA_SPEC_CLASS_NONE, 1, 0},
206 {"zvl128b", ISA_SPEC_CLASS_NONE, 1, 0},
207 {"zvl256b", ISA_SPEC_CLASS_NONE, 1, 0},
208 {"zvl512b", ISA_SPEC_CLASS_NONE, 1, 0},
209 {"zvl1024b", ISA_SPEC_CLASS_NONE, 1, 0},
210 {"zvl2048b", ISA_SPEC_CLASS_NONE, 1, 0},
211 {"zvl4096b", ISA_SPEC_CLASS_NONE, 1, 0},
212 {"zvl8192b", ISA_SPEC_CLASS_NONE, 1, 0},
213 {"zvl16384b", ISA_SPEC_CLASS_NONE, 1, 0},
214 {"zvl32768b", ISA_SPEC_CLASS_NONE, 1, 0},
215 {"zvl65536b", ISA_SPEC_CLASS_NONE, 1, 0},
217 {"zfh", ISA_SPEC_CLASS_NONE, 1, 0},
218 {"zfhmin", ISA_SPEC_CLASS_NONE, 1, 0},
220 {"zmmul", ISA_SPEC_CLASS_NONE, 1, 0},
222 {"svinval", ISA_SPEC_CLASS_NONE, 1, 0},
223 {"svnapot", ISA_SPEC_CLASS_NONE, 1, 0},
225 {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0},
226 {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0},
227 {"xtheadbs", ISA_SPEC_CLASS_NONE, 1, 0},
228 {"xtheadcmo", ISA_SPEC_CLASS_NONE, 1, 0},
229 {"xtheadcondmov", ISA_SPEC_CLASS_NONE, 1, 0},
230 {"xtheadfmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
231 {"xtheadfmv", ISA_SPEC_CLASS_NONE, 1, 0},
232 {"xtheadint", ISA_SPEC_CLASS_NONE, 1, 0},
233 {"xtheadmac", ISA_SPEC_CLASS_NONE, 1, 0},
234 {"xtheadmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
235 {"xtheadmempair", ISA_SPEC_CLASS_NONE, 1, 0},
236 {"xtheadsync", ISA_SPEC_CLASS_NONE, 1, 0},
238 /* Terminate the list. */
239 {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
242 /* Combine extensions defined in this table */
243 static const struct riscv_ext_version riscv_combine_info[] =
245 {"zk", ISA_SPEC_CLASS_NONE, 1, 0},
246 {"zkn", ISA_SPEC_CLASS_NONE, 1, 0},
247 {"zks", ISA_SPEC_CLASS_NONE, 1, 0},
248 /* Terminate the list. */
249 {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
252 static const riscv_cpu_info riscv_cpu_tables[] =
254 #define RISCV_CORE(CORE_NAME, ARCH, TUNE) \
255 {CORE_NAME, ARCH, TUNE},
256 #include "../../../config/riscv/riscv-cores.def"
260 static const char *riscv_tunes[] =
262 #define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO) \
264 #include "../../../config/riscv/riscv-cores.def"
268 static const char *riscv_supported_std_ext (void);
270 static riscv_subset_list *current_subset_list = NULL;
272 const riscv_subset_list *riscv_current_subset_list ()
274 return current_subset_list;
277 /* struct for recording multi-lib info. */
278 struct riscv_multi_lib_info_t {
280 std::string arch_str;
282 std::vector<std::string> conds;
283 riscv_subset_list *subset_list;
285 static bool parse (struct riscv_multi_lib_info_t *,
287 const std::vector<std::string> &);
290 /* Flag for checking if there is no suitable multi-lib found. */
291 static bool riscv_no_matched_multi_lib;
293 /* Used for record value of -march and -mabi. */
294 static std::string riscv_current_arch_str;
295 static std::string riscv_current_abi_str;
297 riscv_subset_t::riscv_subset_t ()
298 : name (), major_version (0), minor_version (0), next (NULL),
299 explicit_version_p (false), implied_p (false)
303 riscv_subset_list::riscv_subset_list (const char *arch, location_t loc)
304 : m_arch (arch), m_loc (loc), m_head (NULL), m_tail (NULL), m_xlen (0)
308 riscv_subset_list::~riscv_subset_list ()
313 riscv_subset_t *item = this->m_head;
316 riscv_subset_t *next = item->next;
322 /* Compute the match score of two arch string, return 0 if incompatible. */
324 riscv_subset_list::match_score (riscv_subset_list *list) const
328 bool has_a_ext, list_has_a_ext;
330 /* Impossible to match if XLEN is different. */
331 if (list->m_xlen != this->m_xlen)
334 /* There is different code gen in libstdc++ and libatomic between w/ A-ext
335 and w/o A-ext, and it not work if using soft and hard atomic mechanism
336 at same time, so they are incompatible. */
337 has_a_ext = this->lookup ("a") != NULL;
338 list_has_a_ext = list->lookup ("a") != NULL;
340 if (has_a_ext != list_has_a_ext)
344 /* list must be subset of current this list, otherwise it not safe to
346 TODO: We might give different weight for each extension, but the rule could
348 TODO: We might consider the version of each extension. */
349 for (s = list->m_head; s != NULL; s = s->next)
350 if (this->lookup (s->name.c_str ()) != NULL)
358 /* Get the rank for single-letter subsets, lower value meaning higher
362 single_letter_subset_rank (char ext)
376 const char *all_ext = riscv_supported_std_ext ();
377 const char *ext_pos = strchr (all_ext, ext);
379 /* If got an unknown extension letter, then give it an alphabetical
380 order, but after all known standard extension. */
381 rank = strlen (all_ext) + ext - 'a';
383 rank = (int)(ext_pos - all_ext) + 2 /* e and i has higher rank. */;
388 /* Get the rank for multi-letter subsets, lower value meaning higher
392 multi_letter_subset_rank (const std::string &subset)
394 gcc_assert (subset.length () >= 2);
397 /* The order between multi-char extensions: s -> z -> x. */
398 char multiletter_class = subset[0];
399 switch (multiletter_class)
415 if (multiletter_class == 'z')
416 /* Order for z extension on spec: If multiple "Z" extensions are named, they
417 should be ordered first by category, then alphabetically within a
418 category - for example, "Zicsr_Zifencei_Zam". */
419 low_order = single_letter_subset_rank (subset[1]);
423 return (high_order << 8) + low_order;
428 Returns an integral value indicating the relationship between the subsets:
429 Return value indicates
430 -1 B has higher order than A.
431 0 A and B are same subset.
432 1 A has higher order than B.
437 subset_cmp (const std::string &a, const std::string &b)
442 size_t a_len = a.length ();
443 size_t b_len = b.length ();
445 /* Single-letter extension always get higher order than
446 multi-letter extension. */
447 if (a_len == 1 && b_len != 1)
450 if (a_len != 1 && b_len == 1)
453 if (a_len == 1 && b_len == 1)
455 int rank_a = single_letter_subset_rank (a[0]);
456 int rank_b = single_letter_subset_rank (b[0]);
465 int rank_a = multi_letter_subset_rank(a);
466 int rank_b = multi_letter_subset_rank(b);
468 /* Using alphabetical/lexicographical order if they have same rank. */
469 if (rank_a == rank_b)
470 /* The return value of strcmp has opposite meaning. */
471 return -strcmp (a.c_str (), b.c_str ());
473 return (rank_a < rank_b) ? 1 : -1;
477 /* Add new subset to list. */
480 riscv_subset_list::add (const char *subset, int major_version,
481 int minor_version, bool explicit_version_p,
484 riscv_subset_t *ext = lookup (subset);
490 /* We won't add impiled `ext` if it already in list. */
491 gcc_assert (!implied_p);
492 ext->implied_p = implied_p;
493 ext->major_version = major_version;
494 ext->minor_version = minor_version;
499 "%<-march=%s%>: extension %qs appear more than one time",
506 riscv_subset_t *s = new riscv_subset_t ();
513 s->major_version = major_version;
514 s->minor_version = minor_version;
515 s->explicit_version_p = explicit_version_p;
516 s->implied_p = implied_p;
525 /* e, i or g should be first subext, never come here. */
526 gcc_assert (subset[0] != 'e'
528 && subset[0] != 'g');
530 if (m_tail == m_head)
532 gcc_assert (m_head->next == NULL);
538 gcc_assert (m_head->next != NULL);
540 /* Subset list must in canonical order, but implied subset won't
541 add in canonical order. */
542 for (itr = m_head; itr->next != NULL; itr = itr->next)
544 riscv_subset_t *next = itr->next;
545 int cmp = subset_cmp (s->name, next->name);
546 gcc_assert (cmp != 0);
556 /* Insert at tail of the list. */
562 get_default_version (const char *ext,
563 unsigned int *major_version,
564 unsigned int *minor_version)
566 const riscv_ext_version *ext_ver;
567 for (ext_ver = &riscv_ext_version_table[0];
568 ext_ver->name != NULL;
570 if (strcmp (ext, ext_ver->name) == 0)
572 if ((ext_ver->isa_spec_class == riscv_isa_spec) ||
573 (ext_ver->isa_spec_class == ISA_SPEC_CLASS_NONE))
575 *major_version = ext_ver->major_version;
576 *minor_version = ext_ver->minor_version;
581 /* Not found version info. */
586 /* Add new subset to list, but using default version from ISA spec version. */
589 riscv_subset_list::add (const char *subset, bool implied_p)
591 unsigned int major_version = 0, minor_version = 0;
593 get_default_version (subset, &major_version, &minor_version);
595 add (subset, major_version, minor_version, false, implied_p);
598 /* Convert subset info to string with explicit version info,
599 VERSION_P to determine append version info or not. */
602 riscv_subset_list::to_string (bool version_p) const
604 std::ostringstream oss;
605 oss << "rv" << m_xlen;
608 riscv_subset_t *subset;
610 bool skip_zifencei = false;
611 bool skip_zicsr = false;
614 /* For RISC-V ISA version 2.2 or earlier version, zicsr and zifencei is
615 included in the base ISA. */
616 if (riscv_isa_spec == ISA_SPEC_CLASS_2P2)
618 skip_zifencei = true;
622 for (subset = m_head; subset != NULL; subset = subset->next)
623 if (subset->name == "i")
625 i2p0 = subset->major_version == 2 && subset->minor_version == 0;
629 #ifndef HAVE_AS_MISA_SPEC
630 /* Skip since older binutils doesn't recognize zicsr. */
633 #ifndef HAVE_AS_MARCH_ZIFENCEI
634 /* Skip since older binutils doesn't recognize zifencei, we made
635 a mistake in that binutils 2.35 supports zicsr but not zifencei. */
636 skip_zifencei = true;
639 for (subset = m_head; subset != NULL; subset = subset->next)
641 if (((subset->implied_p && skip_zifencei) || i2p0) &&
642 subset->name == "zifencei")
645 if (((subset->implied_p && skip_zicsr) || i2p0) &&
646 subset->name == "zicsr")
649 /* For !version_p, we only separate extension with underline for
650 multi-letter extension. */
653 || subset->explicit_version_p
654 || subset->name.length() > 1))
660 /* Let binutils decide the extension version if we don't know. */
661 if ((version_p || subset->explicit_version_p) &&
662 (subset->major_version != 0 || subset->minor_version != 0))
663 oss << subset->major_version
665 << subset->minor_version;
671 /* Find subset in list with version checking, return NULL if not found.
672 major/minor version checking can be ignored if major_version/minor_version
673 is RISCV_DONT_CARE_VERSION. */
676 riscv_subset_list::lookup (const char *subset, int major_version,
677 int minor_version) const
681 for (s = m_head; s != NULL; s = s->next)
682 if (strcasecmp (s->name.c_str (), subset) == 0)
684 if ((major_version != RISCV_DONT_CARE_VERSION)
685 && (s->major_version != major_version))
688 if ((minor_version != RISCV_DONT_CARE_VERSION)
689 && (s->minor_version != minor_version))
698 /* Return string which contains all supported standard extensions in
702 riscv_supported_std_ext (void)
704 return "mafdqlcbkjtpvnh";
707 /* Parsing subset version.
710 Points to the end of version
713 `ext`: This extension.
714 `p`: Current parsing position.
715 `major_version`: Parsing result of major version, using
716 default_major_version if version is not present in arch string.
717 `minor_version`: Parsing result of minor version, set to 0 if version is
718 not present in arch string, but set to `default_minor_version` if
719 `major_version` using default_major_version.
720 `std_ext_p`: True if parsing std extension.
721 `explicit_version_p`: True if this subset is not using default version. */
724 riscv_subset_list::parsing_subset_version (const char *ext,
726 unsigned *major_version,
727 unsigned *minor_version,
729 bool *explicit_version_p)
732 unsigned version = 0;
735 *explicit_version_p = false;
737 /* If we got `p`, that means we are still parsing standard extension. */
738 gcc_assert (std_ext_p || *p != 'p');
745 if (!ISDIGIT (*(p+1)))
747 error_at (m_loc, "%<-march=%s%>: expect number "
748 "after %<%dp%>", m_arch, version);
753 error_at (m_loc, "%<-march=%s%>: for %<%s%dp%dp?%>, version "
754 "number with more than 2 level is not supported",
755 m_arch, ext, major, version);
762 else if (ISDIGIT (*p))
763 version = (version * 10) + (*p - '0');
774 if (major == 0 && minor == 0)
775 get_default_version (ext, major_version, minor_version);
778 *explicit_version_p = true;
779 *major_version = major;
780 *minor_version = minor;
785 /* Parsing function for standard extensions.
788 Points to the end of extensions.
791 `p`: Current parsing position. */
794 riscv_subset_list::parse_std_ext (const char *p)
796 const char *all_std_exts = riscv_supported_std_ext ();
797 const char *std_exts = all_std_exts;
799 unsigned major_version = 0;
800 unsigned minor_version = 0;
802 bool explicit_version_p = false;
804 /* First letter must start with i, e or g. */
809 p = parsing_subset_version ("i", p, &major_version, &minor_version,
810 /* std_ext_p= */ true, &explicit_version_p);
811 add ("i", major_version, minor_version, explicit_version_p, false);
816 p = parsing_subset_version ("e", p, &major_version, &minor_version,
817 /* std_ext_p= */ true, &explicit_version_p);
819 add ("e", major_version, minor_version, explicit_version_p, false);
823 error_at (m_loc, "%<-march=%s%>: rv%de is not a valid base ISA",
831 p = parsing_subset_version ("g", p, &major_version, &minor_version,
832 /* std_ext_p= */ true, &explicit_version_p);
833 if (major_version != 0 || minor_version != 0)
835 warning_at (m_loc, 0, "version of %<g%> will be omitted, please "
836 "specify version for individual extension");
839 /* We have special rule for G, we disallow rv32gm2p but allow rv32g_zicsr
840 here, basically we treating G expand to imafd and implied zicsr and
849 add ("zifencei", true);
854 error_at (m_loc, "%<-march=%s%>: first ISA subset must be %<e%>, "
855 "%<i%> or %<g%>", m_arch);
859 while (p != NULL && *p)
861 char subset[2] = {0, 0};
863 if (*p == 'x' || *p == 's' || *p == 'z')
874 /* Checking canonical order. */
875 while (*std_exts && std_ext != *std_exts)
878 if (std_ext != *std_exts)
880 if (strchr (all_std_exts, std_ext) == NULL)
881 error_at (m_loc, "%<-march=%s%>: unsupported ISA subset %<%c%>",
885 "%<-march=%s%>: ISA string is not in canonical order. "
886 "%<%c%>", m_arch, *p);
895 p = parsing_subset_version (subset, p, &major_version, &minor_version,
896 /* std_ext_p= */ true, &explicit_version_p);
898 add (subset, major_version, minor_version, explicit_version_p, false);
904 /* Check any implied extensions for EXT. */
906 riscv_subset_list::handle_implied_ext (riscv_subset_t *ext)
908 const riscv_implied_info_t *implied_info;
909 for (implied_info = &riscv_implied_info[0];
913 if (strcmp (ext->name.c_str (), implied_info->ext) != 0)
916 /* Skip if implied extension already present. */
917 if (lookup (implied_info->implied_ext))
920 /* Version of implied extension will get from current ISA spec
922 add (implied_info->implied_ext, true);
925 /* For RISC-V ISA version 2.2 or earlier version, zicsr and zifence is
926 included in the base ISA. */
927 if (riscv_isa_spec == ISA_SPEC_CLASS_2P2)
929 if (lookup ("zicsr") == NULL)
932 if (lookup ("zifencei") == NULL)
933 add ("zifencei", true);
937 /* Check any combine extensions for EXT. */
939 riscv_subset_list::handle_combine_ext ()
941 const riscv_ext_version *combine_info;
942 const riscv_implied_info_t *implied_info;
943 bool is_combined = false;
945 for (combine_info = &riscv_combine_info[0]; combine_info->name;
948 /* Skip if combine extensions are present */
949 if (lookup (combine_info->name))
952 /* Find all extensions of the combine extension */
953 for (implied_info = &riscv_implied_info[0]; implied_info->ext;
956 /* Skip if implied extension don't match combine extension */
957 if (strcmp (combine_info->name, implied_info->ext) != 0)
960 if (lookup (implied_info->implied_ext))
969 /* Add combine extensions */
972 if (lookup (combine_info->name) == NULL)
974 add (combine_info->name, combine_info->major_version,
975 combine_info->minor_version, false, true);
981 /* Parsing function for multi-letter extensions.
984 Points to the end of extensions.
987 `p`: Current parsing position.
988 `ext_type`: What kind of extensions, 's', 'z' or 'x'.
989 `ext_type_str`: Full name for kind of extension. */
992 riscv_subset_list::parse_multiletter_ext (const char *p,
993 const char *ext_type,
994 const char *ext_type_str)
996 unsigned major_version = 0;
997 unsigned minor_version = 0;
998 size_t ext_type_len = strlen (ext_type);
1008 if (strncmp (p, ext_type, ext_type_len) != 0)
1011 char *subset = xstrdup (p);
1013 const char *end_of_version;
1014 bool explicit_version_p = false;
1018 size_t end_of_version_pos, i;
1019 bool found_any_number = false;
1020 bool found_minor_version = false;
1022 /* Parse until end of this extension including version number. */
1023 while (*++q != '\0' && *q != '_')
1031 end_of_version_pos = len;
1032 /* Find the begin of version string. */
1033 for (i = len -1; i > 0; --i)
1035 if (ISDIGIT (subset[i]))
1037 found_any_number = true;
1040 /* Might be version seperator, but need to check one more char,
1041 we only allow <major>p<minor>, so we could stop parsing if found
1043 if (subset[i] == 'p' &&
1044 !found_minor_version &&
1045 found_any_number && ISDIGIT (subset[i-1]))
1047 found_minor_version = true;
1051 end_of_version_pos = i + 1;
1055 backup = subset[end_of_version_pos];
1056 subset[end_of_version_pos] = '\0';
1057 ext = xstrdup (subset);
1058 subset[end_of_version_pos] = backup;
1061 = parsing_subset_version (ext, subset + end_of_version_pos, &major_version, &minor_version,
1062 /* std_ext_p= */ false, &explicit_version_p);
1065 if (end_of_version == NULL)
1068 subset[end_of_version_pos] = '\0';
1070 if (strlen (subset) == 1)
1072 error_at (m_loc, "%<-march=%s%>: name of %s must be more than 1 letter",
1073 m_arch, ext_type_str);
1078 add (subset, major_version, minor_version, explicit_version_p, false);
1079 p += end_of_version - subset;
1082 if (*p != '\0' && *p != '_')
1084 error_at (m_loc, "%<-march=%s%>: %s must separate with %<_%>",
1085 m_arch, ext_type_str);
1093 /* Parsing arch string to subset list, return NULL if parsing failed. */
1096 riscv_subset_list::parse (const char *arch, location_t loc)
1098 riscv_subset_list *subset_list = new riscv_subset_list (arch, loc);
1099 riscv_subset_t *itr;
1100 const char *p = arch;
1101 if (startswith (p, "rv32"))
1103 subset_list->m_xlen = 32;
1106 else if (startswith (p, "rv64"))
1108 subset_list->m_xlen = 64;
1113 error_at (loc, "%<-march=%s%>: ISA string must begin with rv32 or rv64",
1118 /* Parsing standard extension. */
1119 p = subset_list->parse_std_ext (p);
1124 /* Parsing supervisor extension. */
1125 p = subset_list->parse_multiletter_ext (p, "s", "supervisor extension");
1130 /* Parsing sub-extensions. */
1131 p = subset_list->parse_multiletter_ext (p, "z", "sub-extension");
1136 /* Parsing non-standard extension. */
1137 p = subset_list->parse_multiletter_ext (p, "x", "non-standard extension");
1144 error_at (loc, "%<-march=%s%>: unexpected ISA string at end: %qs",
1149 for (itr = subset_list->m_head; itr != NULL; itr = itr->next)
1151 subset_list->handle_implied_ext (itr);
1154 subset_list->handle_combine_ext ();
1156 if (subset_list->lookup ("zfinx") && subset_list->lookup ("f"))
1157 error_at (loc, "%<-march=%s%>: z*inx conflicts with floating-point "
1158 "extensions", arch);
1167 /* Return the current arch string. */
1170 riscv_arch_str (bool version_p)
1172 if (current_subset_list)
1173 return current_subset_list->to_string (version_p);
1175 return std::string();
1178 /* Type for pointer to member of gcc_options. */
1179 typedef int (gcc_options::*opt_var_ref_t);
1181 /* Types for recording extension to internal flag. */
1182 struct riscv_ext_flag_table_t {
1184 opt_var_ref_t var_ref;
1188 /* Mapping table between extension to internal flag. */
1189 static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
1191 {"e", &gcc_options::x_target_flags, MASK_RVE},
1192 {"m", &gcc_options::x_target_flags, MASK_MUL},
1193 {"a", &gcc_options::x_target_flags, MASK_ATOMIC},
1194 {"f", &gcc_options::x_target_flags, MASK_HARD_FLOAT},
1195 {"d", &gcc_options::x_target_flags, MASK_DOUBLE_FLOAT},
1196 {"c", &gcc_options::x_target_flags, MASK_RVC},
1197 {"v", &gcc_options::x_target_flags, MASK_FULL_V},
1198 {"v", &gcc_options::x_target_flags, MASK_VECTOR},
1200 {"zicsr", &gcc_options::x_riscv_zi_subext, MASK_ZICSR},
1201 {"zifencei", &gcc_options::x_riscv_zi_subext, MASK_ZIFENCEI},
1203 {"zawrs", &gcc_options::x_riscv_za_subext, MASK_ZAWRS},
1205 {"zba", &gcc_options::x_riscv_zb_subext, MASK_ZBA},
1206 {"zbb", &gcc_options::x_riscv_zb_subext, MASK_ZBB},
1207 {"zbc", &gcc_options::x_riscv_zb_subext, MASK_ZBC},
1208 {"zbs", &gcc_options::x_riscv_zb_subext, MASK_ZBS},
1210 {"zfinx", &gcc_options::x_riscv_zinx_subext, MASK_ZFINX},
1211 {"zdinx", &gcc_options::x_riscv_zinx_subext, MASK_ZDINX},
1212 {"zhinx", &gcc_options::x_riscv_zinx_subext, MASK_ZHINX},
1213 {"zhinxmin", &gcc_options::x_riscv_zinx_subext, MASK_ZHINXMIN},
1215 {"zbkb", &gcc_options::x_riscv_zk_subext, MASK_ZBKB},
1216 {"zbkc", &gcc_options::x_riscv_zk_subext, MASK_ZBKC},
1217 {"zbkx", &gcc_options::x_riscv_zk_subext, MASK_ZBKX},
1218 {"zknd", &gcc_options::x_riscv_zk_subext, MASK_ZKND},
1219 {"zkne", &gcc_options::x_riscv_zk_subext, MASK_ZKNE},
1220 {"zknh", &gcc_options::x_riscv_zk_subext, MASK_ZKNH},
1221 {"zkr", &gcc_options::x_riscv_zk_subext, MASK_ZKR},
1222 {"zksed", &gcc_options::x_riscv_zk_subext, MASK_ZKSED},
1223 {"zksh", &gcc_options::x_riscv_zk_subext, MASK_ZKSH},
1224 {"zkt", &gcc_options::x_riscv_zk_subext, MASK_ZKT},
1226 {"zicboz", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOZ},
1227 {"zicbom", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOM},
1228 {"zicbop", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOP},
1230 {"zve32x", &gcc_options::x_target_flags, MASK_VECTOR},
1231 {"zve32f", &gcc_options::x_target_flags, MASK_VECTOR},
1232 {"zve64x", &gcc_options::x_target_flags, MASK_VECTOR},
1233 {"zve64f", &gcc_options::x_target_flags, MASK_VECTOR},
1234 {"zve64d", &gcc_options::x_target_flags, MASK_VECTOR},
1236 /* We don't need to put complete ELEN/ELEN_FP info here, due to the
1237 implication relation of vector extension.
1238 e.g. v -> zve64d ... zve32x, so v has set MASK_VECTOR_ELEN_FP_64,
1239 MASK_VECTOR_ELEN_FP_32, MASK_VECTOR_ELEN_64 and MASK_VECTOR_ELEN_32
1240 due to the extension implication. */
1241 {"zve32x", &gcc_options::x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_32},
1242 {"zve32f", &gcc_options::x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_FP_32},
1243 {"zve64x", &gcc_options::x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_64},
1244 {"zve64f", &gcc_options::x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_FP_32},
1245 {"zve64d", &gcc_options::x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_FP_64},
1247 {"zvl32b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL32B},
1248 {"zvl64b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL64B},
1249 {"zvl128b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL128B},
1250 {"zvl256b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL256B},
1251 {"zvl512b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL512B},
1252 {"zvl1024b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL1024B},
1253 {"zvl2048b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL2048B},
1254 {"zvl4096b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL4096B},
1255 {"zvl8192b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL8192B},
1256 {"zvl16384b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL16384B},
1257 {"zvl32768b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL32768B},
1258 {"zvl65536b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL65536B},
1260 {"zfhmin", &gcc_options::x_riscv_zf_subext, MASK_ZFHMIN},
1261 {"zfh", &gcc_options::x_riscv_zf_subext, MASK_ZFH},
1263 {"zmmul", &gcc_options::x_riscv_zm_subext, MASK_ZMMUL},
1265 {"svinval", &gcc_options::x_riscv_sv_subext, MASK_SVINVAL},
1266 {"svnapot", &gcc_options::x_riscv_sv_subext, MASK_SVNAPOT},
1268 {"xtheadba", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBA},
1269 {"xtheadbb", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBB},
1270 {"xtheadbs", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBS},
1271 {"xtheadcmo", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADCMO},
1272 {"xtheadcondmov", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADCONDMOV},
1273 {"xtheadfmemidx", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADFMEMIDX},
1274 {"xtheadfmv", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADFMV},
1275 {"xtheadint", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADINT},
1276 {"xtheadmac", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADMAC},
1277 {"xtheadmemidx", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADMEMIDX},
1278 {"xtheadmempair", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADMEMPAIR},
1279 {"xtheadsync", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADSYNC},
1284 /* Parse a RISC-V ISA string into an option mask. Must clear or set all arch
1285 dependent mask bits, in case more than one -march string is passed. */
1288 riscv_parse_arch_string (const char *isa,
1289 struct gcc_options *opts,
1292 riscv_subset_list *subset_list;
1293 subset_list = riscv_subset_list::parse (isa, loc);
1299 const riscv_ext_flag_table_t *arch_ext_flag_tab;
1300 /* Clean up target flags before we set. */
1301 for (arch_ext_flag_tab = &riscv_ext_flag_table[0];
1302 arch_ext_flag_tab->ext;
1303 ++arch_ext_flag_tab)
1304 opts->*arch_ext_flag_tab->var_ref &= ~arch_ext_flag_tab->mask;
1306 if (subset_list->xlen () == 32)
1307 opts->x_target_flags &= ~MASK_64BIT;
1308 else if (subset_list->xlen () == 64)
1309 opts->x_target_flags |= MASK_64BIT;
1312 for (arch_ext_flag_tab = &riscv_ext_flag_table[0];
1313 arch_ext_flag_tab->ext;
1314 ++arch_ext_flag_tab)
1316 if (subset_list->lookup (arch_ext_flag_tab->ext))
1317 opts->*arch_ext_flag_tab->var_ref |= arch_ext_flag_tab->mask;
1321 if (current_subset_list)
1322 delete current_subset_list;
1324 current_subset_list = subset_list;
1327 /* Return the riscv_cpu_info entry for CPU, NULL if not found. */
1329 const riscv_cpu_info *
1330 riscv_find_cpu (const char *cpu)
1332 const riscv_cpu_info *cpu_info = &riscv_cpu_tables[0];
1333 for (;cpu_info->name != NULL; ++cpu_info)
1335 const char *name = cpu_info->name;
1336 if (strcmp (cpu, name) == 0)
1342 /* Implement TARGET_HANDLE_OPTION. */
1345 riscv_handle_option (struct gcc_options *opts,
1346 struct gcc_options *opts_set ATTRIBUTE_UNUSED,
1347 const struct cl_decoded_option *decoded,
1350 switch (decoded->opt_index)
1353 riscv_parse_arch_string (decoded->arg, opts, loc);
1357 if (riscv_find_cpu (decoded->arg) == NULL)
1358 error_at (loc, "%<-mcpu=%s%>: unknown CPU",
1367 /* Expand arch string with implied extensions. */
1370 riscv_expand_arch (int argc ATTRIBUTE_UNUSED,
1373 gcc_assert (argc == 1);
1374 location_t loc = UNKNOWN_LOCATION;
1375 riscv_parse_arch_string (argv[0], NULL, loc);
1376 const std::string arch = riscv_arch_str (false);
1378 return xasprintf ("-march=%s", arch.c_str());
1383 /* Expand default -mtune option from -mcpu option, use default --with-tune value
1384 if -mcpu don't have valid value. */
1387 riscv_default_mtune (int argc, const char **argv)
1389 gcc_assert (argc == 2);
1390 const riscv_cpu_info *cpu = riscv_find_cpu (argv[0]);
1391 const char *default_mtune = argv[1];
1395 return default_mtune;
1398 /* Expand arch string with implied extensions from -mcpu option. */
1401 riscv_expand_arch_from_cpu (int argc ATTRIBUTE_UNUSED,
1404 gcc_assert (argc > 0 && argc <= 2);
1405 const char *default_arch_str = NULL;
1406 const char *arch_str = NULL;
1408 default_arch_str = argv[1];
1410 const riscv_cpu_info *cpu = riscv_find_cpu (argv[0]);
1414 if (default_arch_str == NULL)
1417 arch_str = default_arch_str;
1420 arch_str = cpu->arch;
1422 location_t loc = UNKNOWN_LOCATION;
1424 riscv_parse_arch_string (arch_str, NULL, loc);
1425 const std::string arch = riscv_arch_str (false);
1426 return xasprintf ("-march=%s", arch.c_str());
1429 /* Report error if not found suitable multilib. */
1431 riscv_multi_lib_check (int argc ATTRIBUTE_UNUSED,
1432 const char **argv ATTRIBUTE_UNUSED)
1434 if (riscv_no_matched_multi_lib)
1437 "Cannot find suitable multilib set for %<-march=%s%>/%<-mabi=%s%>",
1438 riscv_current_arch_str.c_str (),
1439 riscv_current_abi_str.c_str ());
1444 /* We only override this in bare-metal toolchain. */
1445 #ifdef RISCV_USE_CUSTOMISED_MULTI_LIB
1447 /* Find last switch with the prefix, options are take last one in general,
1448 return NULL if not found, and return the option value if found, it could
1449 return empty string if the option has no value. */
1452 find_last_appear_switch (
1453 const struct switchstr *switches,
1458 size_t len = strlen (prefix);
1460 for (i = 0; i < n_switches; ++i)
1462 const struct switchstr *this_switch = &switches[n_switches - i - 1];
1464 if (this_switch->live_cond & SWITCH_FALSE)
1467 if (strncmp (this_switch->part1, prefix, len) == 0)
1468 return this_switch->part1 + len;
1474 /* Utils functions to check STR is start with PREFIX or not. */
1477 prefixed_with (const std::string &str, const char *prefix)
1479 return strncmp (prefix, str.c_str (), strlen (prefix)) == 0;
1482 /* Parse the path and cond string into riscv_multi_lib_info_t, return false
1483 if parsing failed. */
1486 riscv_multi_lib_info_t::parse (
1487 struct riscv_multi_lib_info_t *multi_lib_info,
1488 const std::string &path,
1489 const std::vector<std::string> &conds)
1491 const char *default_arch_str = STRINGIZING (TARGET_RISCV_DEFAULT_ARCH);
1492 const char *default_abi_str = STRINGIZING (TARGET_RISCV_DEFAULT_ABI);
1493 multi_lib_info->conds = conds;
1496 multi_lib_info->arch_str = default_arch_str;
1497 multi_lib_info->abi_str = default_abi_str;
1501 std::vector<std::string>::const_iterator itr;
1502 for (itr = conds.begin (); itr != conds.end (); ++itr)
1503 if (prefixed_with (*itr, "march="))
1504 multi_lib_info->arch_str = itr->c_str () + strlen ("march=");
1505 else if (prefixed_with (*itr, "mabi="))
1506 multi_lib_info->abi_str = itr->c_str () + strlen ("mabi=");
1508 /* Skip this multi-lib if this configuration is exactly same as
1509 default multi-lib settings. */
1510 if (multi_lib_info->arch_str == default_arch_str
1511 && multi_lib_info->abi_str == default_abi_str)
1515 multi_lib_info->subset_list =
1516 riscv_subset_list::parse (multi_lib_info->arch_str.c_str (), input_location);
1521 /* Checking ARG is not appeared in SWITCHES if NOT_ARG is set or
1522 ARG is appeared if NOT_ARG is not set. */
1526 const struct switchstr *switches,
1528 const std::string &arg,
1532 for (i = 0; i < n_switches; ++i)
1534 const struct switchstr *this_switch = &switches[n_switches - i - 1];
1536 if ((this_switch->live_cond & SWITCH_IGNORE) != 0)
1539 if (this_switch->live_cond & SWITCH_FALSE)
1542 /* ARG should not appear if NOT_ARG is set. */
1543 if (arg == this_switch->part1)
1544 return not_arg ? false : true;
1547 /* Not found ARG? that's ok if NOT_ARG is not set. */
1548 return not_arg ? true : false;
1551 /* Check the other cond is found or not, return -1 if we should reject this
1552 multi-lib option set, otherwise return updated MATCH_SCORE. */
1556 const struct switchstr *switches,
1559 const std::vector<std::string> &conds)
1564 std::vector<std::string>::const_iterator itr;
1565 const char *checking_arg;
1567 if (match_score == 0)
1570 for (itr = conds.begin (); itr != conds.end (); ++itr)
1572 /* We'll check march= and mabi= in other place. */
1573 if (prefixed_with (*itr, "march=") || prefixed_with (*itr, "mabi="))
1576 checking_arg = itr->c_str ();
1577 if (checking_arg[0] == '!')
1581 checking_arg = checking_arg + 1;
1586 ok = riscv_check_cond (switches, n_switches, checking_arg, not_arg);
1594 /* 100 is magic number, it's just used for make sure this multi-lib has
1595 higher priority if we found any some option is listed in the option check
1597 return match_score + ok_count * 100;
1600 /* Implement TARGET_COMPUTE_MULTILIB. */
1602 riscv_compute_multilib (
1603 const struct switchstr *switches,
1605 const char *multilib_dir,
1606 const char *multilib_defaults ATTRIBUTE_UNUSED,
1607 const char *multilib_select,
1608 const char *multilib_matches ATTRIBUTE_UNUSED,
1609 const char *multilib_exclusions ATTRIBUTE_UNUSED,
1610 const char *multilib_reuse ATTRIBUTE_UNUSED)
1613 const char *this_path;
1614 size_t this_path_len;
1616 riscv_no_matched_multi_lib = false;
1617 riscv_subset_list *subset_list = NULL;
1619 std::vector<riscv_multi_lib_info_t> multilib_infos;
1620 std::vector<std::string> option_conds;
1621 std::string option_cond;
1622 riscv_multi_lib_info_t multilib_info;
1624 /* Already found suitable, multi-lib, just use that. */
1625 if (multilib_dir != NULL)
1626 return multilib_dir;
1629 riscv_current_arch_str =
1630 find_last_appear_switch (switches, n_switches, "march=");
1632 riscv_current_abi_str =
1633 find_last_appear_switch (switches, n_switches, "mabi=");
1635 /* Failed to find -march or -mabi, but it should not happened since we have
1636 set both in OPTION_DEFAULT_SPECS. */
1637 if (riscv_current_arch_str.empty () || riscv_current_abi_str.empty ())
1638 return multilib_dir;
1640 subset_list = riscv_subset_list::parse (riscv_current_arch_str.c_str (),
1643 /* Failed to parse -march, fallback to using what gcc use. */
1644 if (subset_list == NULL)
1645 return multilib_dir;
1647 /* Parsing MULTILIB_SELECT, ignore MULTILIB_REUSE here, we have our own rules.
1648 TODO: most codes are grab from gcc.c, maybe we should refine that? */
1649 p = multilib_select;
1653 /* Ignore newlines. */
1660 /* Format of each multilib:
1661 <path> <opt1> <opt2> ... <optN>; */
1668 fatal_error (input_location, "multilib select %qs %qs is invalid",
1669 multilib_select, multilib_reuse);
1674 this_path_len = p - this_path;
1675 multilib_info.path = std::string (this_path, this_path_len);
1677 option_conds.clear ();
1678 /* Pasrse option check list into vector<string>.
1679 e.g. "march=rv64imafd mabi=lp64 !mcmodel=medany" to
1680 ["march=rv64imafd", "mabi=lp64", "!mcmodel=medany"]. */
1685 while (*p == ' ') p++;
1687 while (*p && *p != ' ' && *p != ';')
1688 option_cond.push_back (*p++);
1690 /* Ignore `!march=` and `!mabi=`, we will handle march and mabi
1692 if (option_cond.size ()
1693 && !prefixed_with (option_cond, "!march=")
1694 && !prefixed_with (option_cond, "!mabi="))
1695 option_conds.push_back (option_cond);
1699 riscv_multi_lib_info_t::parse (
1701 std::string (this_path, this_path_len),
1705 multilib_infos.push_back (multilib_info);
1710 int match_score = 0;
1711 int max_match_score = 0;
1712 int best_match_multi_lib = -1;
1713 /* Try to decision which set we should used. */
1714 /* We have 3 level decision tree here, ABI, check input arch/ABI must
1715 be superset of multi-lib arch, and other rest option checking. */
1716 for (size_t i = 0; i < multilib_infos.size (); ++i)
1718 /* Check ABI is same first. */
1719 if (riscv_current_abi_str != multilib_infos[i].abi_str)
1722 /* Found a potential compatible multi-lib setting!
1723 Calculate the match score. */
1724 match_score = subset_list->match_score (multilib_infos[i].subset_list);
1726 /* Checking other cond in the multi-lib setting. */
1727 match_score = riscv_check_conds (switches,
1730 multilib_infos[i].conds);
1732 /* Record highest match score multi-lib setting. */
1733 if (match_score > max_match_score)
1735 best_match_multi_lib = i;
1736 max_match_score = match_score;
1740 if (best_match_multi_lib == -1)
1742 riscv_no_matched_multi_lib = true;
1743 return multilib_dir;
1746 return xstrdup (multilib_infos[best_match_multi_lib].path.c_str ());
1749 #undef TARGET_COMPUTE_MULTILIB
1750 #define TARGET_COMPUTE_MULTILIB riscv_compute_multilib
1754 riscv_get_valid_option_values (int option_code,
1755 const char *prefix ATTRIBUTE_UNUSED)
1757 vec<const char *> v;
1759 opt_code opt = (opt_code) option_code;
1765 const char **tune = &riscv_tunes[0];
1766 for (;*tune; ++tune)
1767 v.safe_push (*tune);
1769 const riscv_cpu_info *cpu_info = &riscv_cpu_tables[0];
1770 for (;cpu_info->name; ++cpu_info)
1771 v.safe_push (cpu_info->name);
1776 const riscv_cpu_info *cpu_info = &riscv_cpu_tables[0];
1777 for (;cpu_info->name; ++cpu_info)
1778 v.safe_push (cpu_info->name);
1788 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1789 static const struct default_options riscv_option_optimization_table[] =
1791 { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
1792 { OPT_LEVELS_2_PLUS, OPT_free, NULL, 1 },
1793 #if TARGET_DEFAULT_ASYNC_UNWIND_TABLES == 1
1794 { OPT_LEVELS_ALL, OPT_fasynchronous_unwind_tables, NULL, 1 },
1795 { OPT_LEVELS_ALL, OPT_funwind_tables, NULL, 1},
1797 { OPT_LEVELS_NONE, 0, NULL, 0 }
1800 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1801 #define TARGET_OPTION_OPTIMIZATION_TABLE riscv_option_optimization_table
1803 #undef TARGET_HANDLE_OPTION
1804 #define TARGET_HANDLE_OPTION riscv_handle_option
1806 #undef TARGET_GET_VALID_OPTION_VALUES
1807 #define TARGET_GET_VALID_OPTION_VALUES riscv_get_valid_option_values
1809 struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;