2fc0f8bffc15643ebd2ba7aead1e84485ee5f118
[platform/upstream/gcc.git] / gcc / common / config / riscv / riscv-common.cc
1 /* Common hooks for RISC-V.
2    Copyright (C) 2016-2023 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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)
9 any later version.
10
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.
15
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/>.  */
19
20 #include <sstream>
21 #include <vector>
22
23 #define INCLUDE_STRING
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "common/common-target.h"
29 #include "common/common-target-def.h"
30 #include "opts.h"
31 #include "flags.h"
32 #include "diagnostic-core.h"
33 #include "config/riscv/riscv-protos.h"
34 #include "config/riscv/riscv-subset.h"
35
36 #ifdef  TARGET_BIG_ENDIAN_DEFAULT
37 #undef  TARGET_DEFAULT_TARGET_FLAGS
38 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
39 #endif
40
41 /* Type for implied ISA info.  */
42 struct riscv_implied_info_t
43 {
44   const char *ext;
45   const char *implied_ext;
46 };
47
48 /* Implied ISA info, must end with NULL sentinel.  */
49 static const riscv_implied_info_t riscv_implied_info[] =
50 {
51   {"d", "f"},
52   {"f", "zicsr"},
53   {"d", "zicsr"},
54
55   {"zdinx", "zfinx"},
56   {"zfinx", "zicsr"},
57   {"zdinx", "zicsr"},
58
59   {"zk", "zkn"},
60   {"zk", "zkr"},
61   {"zk", "zkt"},
62   {"zkn", "zbkb"},
63   {"zkn", "zbkc"},
64   {"zkn", "zbkx"},
65   {"zkn", "zkne"},
66   {"zkn", "zknd"},
67   {"zkn", "zknh"},
68   {"zks", "zbkb"},
69   {"zks", "zbkc"},
70   {"zks", "zbkx"},
71   {"zks", "zksed"},
72   {"zks", "zksh"},
73
74   {"v", "zvl128b"},
75   {"v", "zve64d"},
76
77   {"zve32f", "f"},
78   {"zve64f", "f"},
79   {"zve64d", "d"},
80
81   {"zve32x", "zvl32b"},
82   {"zve32f", "zve32x"},
83   {"zve32f", "zvl32b"},
84
85   {"zve64x", "zve32x"},
86   {"zve64x", "zvl64b"},
87   {"zve64f", "zve32f"},
88   {"zve64f", "zve64x"},
89   {"zve64f", "zvl64b"},
90   {"zve64d", "zve64f"},
91   {"zve64d", "zvl64b"},
92
93   {"zvl64b", "zvl32b"},
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"},
104
105   {"zfh", "zfhmin"},
106   {"zfhmin", "f"},
107   
108   {"zhinx", "zhinxmin"},
109   {"zhinxmin", "zfinx"},
110
111   {NULL, NULL}
112 };
113
114 /* This structure holds version information for specific ISA version.  */
115
116 struct riscv_ext_version
117 {
118   const char *name;
119   enum riscv_isa_spec_class isa_spec_class;
120   int major_version;
121   int minor_version;
122 };
123
124 /* All standard extensions defined in all supported ISA spec.  */
125 static const struct riscv_ext_version riscv_ext_version_table[] =
126 {
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},
131
132   {"i", ISA_SPEC_CLASS_20191213, 2, 1},
133   {"i", ISA_SPEC_CLASS_20190608, 2, 1},
134   {"i", ISA_SPEC_CLASS_2P2,      2, 0},
135
136   {"m", ISA_SPEC_CLASS_20191213, 2, 0},
137   {"m", ISA_SPEC_CLASS_20190608, 2, 0},
138   {"m", ISA_SPEC_CLASS_2P2,      2, 0},
139
140   {"a", ISA_SPEC_CLASS_20191213, 2, 1},
141   {"a", ISA_SPEC_CLASS_20190608, 2, 0},
142   {"a", ISA_SPEC_CLASS_2P2,      2, 0},
143
144   {"f", ISA_SPEC_CLASS_20191213, 2, 2},
145   {"f", ISA_SPEC_CLASS_20190608, 2, 2},
146   {"f", ISA_SPEC_CLASS_2P2,      2, 0},
147
148   {"d", ISA_SPEC_CLASS_20191213, 2, 2},
149   {"d", ISA_SPEC_CLASS_20190608, 2, 2},
150   {"d", ISA_SPEC_CLASS_2P2,      2, 0},
151
152   {"c", ISA_SPEC_CLASS_20191213, 2, 0},
153   {"c", ISA_SPEC_CLASS_20190608, 2, 0},
154   {"c", ISA_SPEC_CLASS_2P2,      2, 0},
155
156   {"h",       ISA_SPEC_CLASS_NONE, 1, 0},
157
158   {"v",       ISA_SPEC_CLASS_NONE, 1, 0},
159
160   {"zicsr", ISA_SPEC_CLASS_20191213, 2, 0},
161   {"zicsr", ISA_SPEC_CLASS_20190608, 2, 0},
162
163   {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0},
164   {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0},
165
166   {"zawrs", ISA_SPEC_CLASS_NONE, 1, 0},
167
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},
172
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},
177
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},
188
189   {"zicboz",ISA_SPEC_CLASS_NONE, 1, 0},
190   {"zicbom",ISA_SPEC_CLASS_NONE, 1, 0},
191   {"zicbop",ISA_SPEC_CLASS_NONE, 1, 0},
192
193   {"zk",    ISA_SPEC_CLASS_NONE, 1, 0},
194   {"zkn",   ISA_SPEC_CLASS_NONE, 1, 0},
195   {"zks",   ISA_SPEC_CLASS_NONE, 1, 0},
196
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},
203
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},
216
217   {"zfh",       ISA_SPEC_CLASS_NONE, 1, 0},
218   {"zfhmin",    ISA_SPEC_CLASS_NONE, 1, 0},
219
220   {"zmmul", ISA_SPEC_CLASS_NONE, 1, 0},
221
222   {"svinval", ISA_SPEC_CLASS_NONE, 1, 0},
223   {"svnapot", ISA_SPEC_CLASS_NONE, 1, 0},
224
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},
237
238   /* Terminate the list.  */
239   {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
240 };
241
242 /* Combine extensions defined in this table  */
243 static const struct riscv_ext_version riscv_combine_info[] =
244 {
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}
250 };
251
252 static const riscv_cpu_info riscv_cpu_tables[] =
253 {
254 #define RISCV_CORE(CORE_NAME, ARCH, TUNE) \
255     {CORE_NAME, ARCH, TUNE},
256 #include "../../../config/riscv/riscv-cores.def"
257     {NULL, NULL, NULL}
258 };
259
260 static const char *riscv_tunes[] =
261 {
262 #define RISCV_TUNE(TUNE_NAME, PIPELINE_MODEL, TUNE_INFO) \
263     TUNE_NAME,
264 #include "../../../config/riscv/riscv-cores.def"
265     NULL
266 };
267
268 static const char *riscv_supported_std_ext (void);
269
270 static riscv_subset_list *current_subset_list = NULL;
271
272 const riscv_subset_list *riscv_current_subset_list ()
273 {
274   return current_subset_list;
275 }
276
277 /* struct for recording multi-lib info.  */
278 struct riscv_multi_lib_info_t {
279   std::string path;
280   std::string arch_str;
281   std::string abi_str;
282   std::vector<std::string> conds;
283   riscv_subset_list *subset_list;
284
285   static bool parse (struct riscv_multi_lib_info_t *,
286                      const std::string &,
287                      const std::vector<std::string> &);
288 };
289
290 /* Flag for checking if there is no suitable multi-lib found.  */
291 static bool riscv_no_matched_multi_lib;
292
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;
296
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)
300 {
301 }
302
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)
305 {
306 }
307
308 riscv_subset_list::~riscv_subset_list ()
309 {
310   if (!m_head)
311     return;
312
313   riscv_subset_t *item = this->m_head;
314   while (item != NULL)
315     {
316       riscv_subset_t *next = item->next;
317       delete item;
318       item = next;
319     }
320 }
321
322 /* Compute the match score of two arch string, return 0 if incompatible.  */
323 int
324 riscv_subset_list::match_score (riscv_subset_list *list) const
325 {
326   riscv_subset_t *s;
327   int score = 0;
328   bool has_a_ext, list_has_a_ext;
329
330   /* Impossible to match if XLEN is different.  */
331   if (list->m_xlen != this->m_xlen)
332     return 0;
333
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;
339
340   if (has_a_ext != list_has_a_ext)
341     return 0;
342
343
344   /* list must be subset of current this list, otherwise it not safe to
345      link.
346      TODO: We might give different weight for each extension, but the rule could
347            be complicated.
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)
351       score++;
352     else
353       return 0;
354
355   return score;
356 }
357
358 /* Get the rank for single-letter subsets, lower value meaning higher
359    priority.  */
360
361 static int
362 single_letter_subset_rank (char ext)
363 {
364   int rank;
365
366   switch (ext)
367     {
368     case 'i':
369       return 0;
370     case 'e':
371       return 1;
372     default:
373       break;
374     }
375
376   const char *all_ext = riscv_supported_std_ext ();
377   const char *ext_pos = strchr (all_ext, ext);
378   if (ext_pos == NULL)
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';
382   else
383     rank = (int)(ext_pos - all_ext) + 2 /* e and i has higher rank.  */;
384
385   return rank;
386 }
387
388 /* Get the rank for multi-letter subsets, lower value meaning higher
389    priority.  */
390
391 static int
392 multi_letter_subset_rank (const std::string &subset)
393 {
394   gcc_assert (subset.length () >= 2);
395   int high_order = -1;
396   int low_order = 0;
397   /* The order between multi-char extensions: s -> z -> x.  */
398   char multiletter_class = subset[0];
399   switch (multiletter_class)
400     {
401     case 's':
402       high_order = 0;
403       break;
404     case 'z':
405       high_order = 1;
406       break;
407     case 'x':
408       high_order = 2;
409       break;
410     default:
411       gcc_unreachable ();
412       return -1;
413     }
414
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]);
420   else
421     low_order = 0;
422
423   return (high_order << 8) + low_order;
424 }
425
426 /* subset compare
427
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.
433
434 */
435
436 static int
437 subset_cmp (const std::string &a, const std::string &b)
438 {
439   if (a == b)
440     return 0;
441
442   size_t a_len = a.length ();
443   size_t b_len = b.length ();
444
445   /* Single-letter extension always get higher order than
446      multi-letter extension.  */
447   if (a_len == 1 && b_len != 1)
448     return 1;
449
450   if (a_len != 1 && b_len == 1)
451     return -1;
452
453   if (a_len == 1 && b_len == 1)
454     {
455       int rank_a = single_letter_subset_rank (a[0]);
456       int rank_b = single_letter_subset_rank (b[0]);
457
458       if (rank_a < rank_b)
459         return 1;
460       else
461         return -1;
462     }
463   else
464     {
465       int rank_a = multi_letter_subset_rank(a);
466       int rank_b = multi_letter_subset_rank(b);
467
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 ());
472       else
473         return (rank_a < rank_b) ? 1 : -1;
474     }
475 }
476
477 /* Add new subset to list.  */
478
479 void
480 riscv_subset_list::add (const char *subset, int major_version,
481                         int minor_version, bool explicit_version_p,
482                         bool implied_p)
483 {
484   riscv_subset_t *ext = lookup (subset);
485
486   if (ext)
487     {
488       if (ext->implied_p)
489         {
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;
495         }
496       else
497         error_at (
498           m_loc,
499           "%<-march=%s%>: extension %qs appear more than one time",
500           m_arch,
501           subset);
502
503       return;
504     }
505
506   riscv_subset_t *s = new riscv_subset_t ();
507   riscv_subset_t *itr;
508
509   if (m_head == NULL)
510     m_head = s;
511
512   s->name = subset;
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;
517   s->next = NULL;
518
519   if (m_tail == NULL)
520     {
521       m_tail = s;
522       return;
523     }
524
525   /* e, i or g should be first subext, never come here.  */
526   gcc_assert (subset[0] != 'e'
527               && subset[0] != 'i'
528               && subset[0] != 'g');
529
530   if (m_tail == m_head)
531     {
532       gcc_assert (m_head->next == NULL);
533       m_head->next = s;
534       m_tail = s;
535       return;
536     }
537
538   gcc_assert (m_head->next != NULL);
539
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)
543     {
544       riscv_subset_t *next = itr->next;
545       int cmp = subset_cmp (s->name, next->name);
546       gcc_assert (cmp != 0);
547
548       if (cmp > 0)
549         {
550           s->next = next;
551           itr->next = s;
552           return;
553         }
554     }
555
556   /* Insert at tail of the list.  */
557   itr->next = s;
558   m_tail = s;
559 }
560
561 static void
562 get_default_version (const char *ext,
563                      unsigned int *major_version,
564                      unsigned int *minor_version)
565 {
566   const riscv_ext_version *ext_ver;
567   for (ext_ver = &riscv_ext_version_table[0];
568        ext_ver->name != NULL;
569        ++ext_ver)
570     if (strcmp (ext, ext_ver->name) == 0)
571       {
572         if ((ext_ver->isa_spec_class == riscv_isa_spec) ||
573             (ext_ver->isa_spec_class == ISA_SPEC_CLASS_NONE))
574           {
575             *major_version = ext_ver->major_version;
576             *minor_version = ext_ver->minor_version;
577             return;
578           }
579       }
580
581   /* Not found version info.  */
582   *major_version = 0;
583   *minor_version = 0;
584 }
585
586 /* Add new subset to list, but using default version from ISA spec version.  */
587
588 void
589 riscv_subset_list::add (const char *subset, bool implied_p)
590 {
591   unsigned int major_version = 0, minor_version = 0;
592
593   get_default_version (subset, &major_version, &minor_version);
594
595   add (subset, major_version, minor_version, false, implied_p);
596 }
597
598 /* Convert subset info to string with explicit version info,
599    VERSION_P to determine append version info or not.  */
600
601 std::string
602 riscv_subset_list::to_string (bool version_p) const
603 {
604   std::ostringstream oss;
605   oss << "rv" << m_xlen;
606
607   bool first = true;
608   riscv_subset_t *subset;
609
610   bool skip_zifencei = false;
611   bool skip_zicsr = false;
612   bool i2p0 = false;
613
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)
617     {
618       skip_zifencei = true;
619       skip_zicsr = true;
620     }
621
622   for (subset = m_head; subset != NULL; subset = subset->next)
623     if (subset->name == "i")
624       {
625         i2p0 = subset->major_version == 2 && subset->minor_version == 0;
626         break;
627       }
628
629 #ifndef HAVE_AS_MISA_SPEC
630   /* Skip since older binutils doesn't recognize zicsr.  */
631   skip_zicsr = true;
632 #endif
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;
637 #endif
638
639   for (subset = m_head; subset != NULL; subset = subset->next)
640     {
641       if (((subset->implied_p && skip_zifencei) || i2p0) &&
642           subset->name == "zifencei")
643         continue;
644
645       if (((subset->implied_p && skip_zicsr) || i2p0) &&
646           subset->name == "zicsr")
647         continue;
648
649       /* For !version_p, we only separate extension with underline for
650          multi-letter extension.  */
651       if (!first &&
652           (version_p
653            || subset->explicit_version_p
654            || subset->name.length() > 1))
655         oss << '_';
656       first = false;
657
658       oss << subset->name;
659
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
664              << 'p'
665              << subset->minor_version;
666     }
667
668   return oss.str ();
669 }
670
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.  */
674
675 riscv_subset_t *
676 riscv_subset_list::lookup (const char *subset, int major_version,
677                            int minor_version) const
678 {
679   riscv_subset_t *s;
680
681   for (s = m_head; s != NULL; s = s->next)
682     if (strcasecmp (s->name.c_str (), subset) == 0)
683       {
684         if ((major_version != RISCV_DONT_CARE_VERSION)
685             && (s->major_version != major_version))
686           return NULL;
687
688         if ((minor_version != RISCV_DONT_CARE_VERSION)
689             && (s->minor_version != minor_version))
690           return NULL;
691
692         return s;
693       }
694
695   return s;
696 }
697
698 /* Return string which contains all supported standard extensions in
699    canonical order.  */
700
701 static const char *
702 riscv_supported_std_ext (void)
703 {
704   return "mafdqlcbkjtpvnh";
705 }
706
707 /* Parsing subset version.
708
709    Return Value:
710      Points to the end of version
711
712    Arguments:
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.  */
722
723 const char *
724 riscv_subset_list::parsing_subset_version (const char *ext,
725                                            const char *p,
726                                            unsigned *major_version,
727                                            unsigned *minor_version,
728                                            bool std_ext_p,
729                                            bool *explicit_version_p)
730 {
731   bool major_p = true;
732   unsigned version = 0;
733   unsigned major = 0;
734   unsigned minor = 0;
735   *explicit_version_p = false;
736
737   /* If we got `p`, that means we are still parsing standard extension.  */
738   gcc_assert (std_ext_p || *p != 'p');
739
740   if (*p != 'p') {
741     for (; *p; ++p)
742       {
743         if (*p == 'p')
744           {
745             if (!ISDIGIT (*(p+1)))
746               {
747                 error_at (m_loc, "%<-march=%s%>: expect number "
748                           "after %<%dp%>", m_arch, version);
749                 return NULL;
750               }
751             if (!major_p)
752               {
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);
756                 return NULL;
757               }
758             major = version;
759             major_p = false;
760             version = 0;
761           }
762         else if (ISDIGIT (*p))
763           version = (version * 10) + (*p - '0');
764         else
765           break;
766       }
767   }
768
769   if (major_p)
770     major = version;
771   else
772     minor = version;
773
774   if (major == 0 && minor == 0)
775     get_default_version (ext, major_version, minor_version);
776   else
777     {
778       *explicit_version_p = true;
779       *major_version = major;
780       *minor_version = minor;
781     }
782   return p;
783 }
784
785 /* Parsing function for standard extensions.
786
787    Return Value:
788      Points to the end of extensions.
789
790    Arguments:
791      `p`: Current parsing position.  */
792
793 const char *
794 riscv_subset_list::parse_std_ext (const char *p)
795 {
796   const char *all_std_exts = riscv_supported_std_ext ();
797   const char *std_exts = all_std_exts;
798
799   unsigned major_version = 0;
800   unsigned minor_version = 0;
801   char std_ext = '\0';
802   bool explicit_version_p = false;
803
804   /* First letter must start with i, e or g.  */
805   switch (*p)
806     {
807     case 'i':
808       p++;
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);
812       break;
813
814     case 'e':
815       p++;
816       p = parsing_subset_version ("e", p, &major_version, &minor_version,
817                                   /* std_ext_p= */ true, &explicit_version_p);
818
819       add ("e", major_version, minor_version, explicit_version_p, false);
820
821       if (m_xlen > 32)
822         {
823           error_at (m_loc, "%<-march=%s%>: rv%de is not a valid base ISA",
824                     m_arch, m_xlen);
825           return NULL;
826         }
827       break;
828
829     case 'g':
830       p++;
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)
834         {
835           warning_at (m_loc, 0, "version of %<g%> will be omitted, please "
836                                 "specify version for individual extension");
837         }
838
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
841          zifencei.  */
842
843       add ("i", false);
844       add ("m", false);
845       add ("a", false);
846       add ("f", false);
847       add ("d", false);
848       add ("zicsr", true);
849       add ("zifencei", true);
850
851       break;
852
853     default:
854       error_at (m_loc, "%<-march=%s%>: first ISA subset must be %<e%>, "
855                 "%<i%> or %<g%>", m_arch);
856       return NULL;
857     }
858
859   while (p != NULL && *p)
860     {
861       char subset[2] = {0, 0};
862
863       if (*p == 'x' || *p == 's' || *p == 'z')
864         break;
865
866       if (*p == '_')
867         {
868           p++;
869           continue;
870         }
871
872       std_ext = *p;
873
874       /* Checking canonical order.  */
875       while (*std_exts && std_ext != *std_exts)
876         std_exts++;
877
878       if (std_ext != *std_exts)
879         {
880           if (strchr (all_std_exts, std_ext) == NULL)
881             error_at (m_loc, "%<-march=%s%>: unsupported ISA subset %<%c%>",
882                       m_arch, *p);
883           else
884             error_at (m_loc,
885                       "%<-march=%s%>: ISA string is not in canonical order. "
886                       "%<%c%>", m_arch, *p);
887           return NULL;
888         }
889
890       std_exts++;
891
892       p++;
893       subset[0] = std_ext;
894
895       p = parsing_subset_version (subset, p, &major_version, &minor_version,
896                                   /* std_ext_p= */ true, &explicit_version_p);
897
898       add (subset, major_version, minor_version, explicit_version_p, false);
899     }
900   return p;
901 }
902
903
904 /* Check any implied extensions for EXT.  */
905 void
906 riscv_subset_list::handle_implied_ext (riscv_subset_t *ext)
907 {
908   const riscv_implied_info_t *implied_info;
909   for (implied_info = &riscv_implied_info[0];
910        implied_info->ext;
911        ++implied_info)
912     {
913       if (strcmp (ext->name.c_str (), implied_info->ext) != 0)
914         continue;
915
916       /* Skip if implied extension already present.  */
917       if (lookup (implied_info->implied_ext))
918         continue;
919
920       /* Version of implied extension will get from current ISA spec
921          version.  */
922       add (implied_info->implied_ext, true);
923     }
924
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)
928     {
929       if (lookup ("zicsr") == NULL)
930         add ("zicsr", true);
931
932       if (lookup ("zifencei") == NULL)
933         add ("zifencei", true);
934     }
935 }
936
937 /* Check any combine extensions for EXT.  */
938 void
939 riscv_subset_list::handle_combine_ext ()
940 {
941   const riscv_ext_version *combine_info;
942   const riscv_implied_info_t *implied_info;
943   bool is_combined = false;
944
945   for (combine_info = &riscv_combine_info[0]; combine_info->name;
946        ++combine_info)
947     {
948       /* Skip if combine extensions are present */
949       if (lookup (combine_info->name))
950         continue;
951
952       /* Find all extensions of the combine extension   */
953       for (implied_info = &riscv_implied_info[0]; implied_info->ext;
954            ++implied_info)
955         {
956           /* Skip if implied extension don't match combine extension */
957           if (strcmp (combine_info->name, implied_info->ext) != 0)
958             continue;
959
960           if (lookup (implied_info->implied_ext))
961             is_combined = true;
962           else
963             {
964               is_combined = false;
965               break;
966             }
967         }
968
969       /* Add combine extensions */
970       if (is_combined)
971         {
972           if (lookup (combine_info->name) == NULL)
973             {
974               add (combine_info->name, combine_info->major_version,
975                    combine_info->minor_version, false, true);
976             }
977         }
978     }
979 }
980
981 /* Parsing function for multi-letter extensions.
982
983    Return Value:
984      Points to the end of extensions.
985
986    Arguments:
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.  */
990
991 const char *
992 riscv_subset_list::parse_multiletter_ext (const char *p,
993                                           const char *ext_type,
994                                           const char *ext_type_str)
995 {
996   unsigned major_version = 0;
997   unsigned minor_version = 0;
998   size_t ext_type_len = strlen (ext_type);
999
1000   while (*p)
1001     {
1002       if (*p == '_')
1003         {
1004           p++;
1005           continue;
1006         }
1007
1008       if (strncmp (p, ext_type, ext_type_len) != 0)
1009         break;
1010
1011       char *subset = xstrdup (p);
1012       char *q = subset;
1013       const char *end_of_version;
1014       bool explicit_version_p = false;
1015       char *ext;
1016       char backup;
1017       size_t len;
1018       size_t end_of_version_pos, i;
1019       bool found_any_number = false;
1020       bool found_minor_version = false;
1021
1022       /* Parse until end of this extension including version number.  */
1023       while (*++q != '\0' && *q != '_')
1024         ;
1025
1026       backup = *q;
1027       *q = '\0';
1028       len = q - subset;
1029       *q = backup;
1030
1031       end_of_version_pos = len;
1032       /* Find the begin of version string.  */
1033       for (i = len -1; i > 0; --i)
1034         {
1035           if (ISDIGIT (subset[i]))
1036             {
1037               found_any_number = true;
1038               continue;
1039             }
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
1042              any more `p`.  */
1043           if (subset[i] == 'p' &&
1044               !found_minor_version &&
1045               found_any_number && ISDIGIT (subset[i-1]))
1046             {
1047               found_minor_version = true;
1048               continue;
1049             }
1050
1051           end_of_version_pos = i + 1;
1052           break;
1053         }
1054
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;
1059
1060       end_of_version
1061         = parsing_subset_version (ext, subset + end_of_version_pos, &major_version, &minor_version,
1062                                   /* std_ext_p= */ false, &explicit_version_p);
1063       free (ext);
1064
1065       if (end_of_version == NULL)
1066         return NULL;
1067
1068       subset[end_of_version_pos] = '\0';
1069
1070       if (strlen (subset) == 1)
1071         {
1072           error_at (m_loc, "%<-march=%s%>: name of %s must be more than 1 letter",
1073                     m_arch, ext_type_str);
1074           free (subset);
1075           return NULL;
1076         }
1077
1078       add (subset, major_version, minor_version, explicit_version_p, false);
1079       p += end_of_version - subset;
1080       free (subset);
1081
1082       if (*p != '\0' && *p != '_')
1083         {
1084           error_at (m_loc, "%<-march=%s%>: %s must separate with %<_%>",
1085                     m_arch, ext_type_str);
1086           return NULL;
1087         }
1088     }
1089
1090   return p;
1091 }
1092
1093 /* Parsing arch string to subset list, return NULL if parsing failed.  */
1094
1095 riscv_subset_list *
1096 riscv_subset_list::parse (const char *arch, location_t loc)
1097 {
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"))
1102     {
1103       subset_list->m_xlen = 32;
1104       p += 4;
1105     }
1106   else if (startswith (p, "rv64"))
1107     {
1108       subset_list->m_xlen = 64;
1109       p += 4;
1110     }
1111   else
1112     {
1113       error_at (loc, "%<-march=%s%>: ISA string must begin with rv32 or rv64",
1114                 arch);
1115       goto fail;
1116     }
1117
1118   /* Parsing standard extension.  */
1119   p = subset_list->parse_std_ext (p);
1120
1121   if (p == NULL)
1122     goto fail;
1123
1124   /* Parsing supervisor extension.  */
1125   p = subset_list->parse_multiletter_ext (p, "s", "supervisor extension");
1126
1127   if (p == NULL)
1128     goto fail;
1129
1130   /* Parsing sub-extensions.  */
1131   p = subset_list->parse_multiletter_ext (p, "z", "sub-extension");
1132
1133   if (p == NULL)
1134     goto fail;
1135
1136   /* Parsing non-standard extension.  */
1137   p = subset_list->parse_multiletter_ext (p, "x", "non-standard extension");
1138
1139   if (p == NULL)
1140     goto fail;
1141
1142   if (*p != '\0')
1143     {
1144       error_at (loc, "%<-march=%s%>: unexpected ISA string at end: %qs",
1145                arch, p);
1146       goto fail;
1147     }
1148
1149   for (itr = subset_list->m_head; itr != NULL; itr = itr->next)
1150     {
1151       subset_list->handle_implied_ext (itr);
1152     }
1153
1154   subset_list->handle_combine_ext ();
1155
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);
1159
1160   return subset_list;
1161
1162 fail:
1163   delete subset_list;
1164   return NULL;
1165 }
1166
1167 /* Return the current arch string.  */
1168
1169 std::string
1170 riscv_arch_str (bool version_p)
1171 {
1172   if (current_subset_list)
1173     return current_subset_list->to_string (version_p);
1174   else
1175     return std::string();
1176 }
1177
1178 /* Type for pointer to member of gcc_options.  */
1179 typedef int (gcc_options::*opt_var_ref_t);
1180
1181 /* Types for recording extension to internal flag.  */
1182 struct riscv_ext_flag_table_t {
1183   const char *ext;
1184   opt_var_ref_t var_ref;
1185   int mask;
1186 };
1187
1188 /* Mapping table between extension to internal flag.  */
1189 static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
1190 {
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},
1199
1200   {"zicsr",    &gcc_options::x_riscv_zi_subext, MASK_ZICSR},
1201   {"zifencei", &gcc_options::x_riscv_zi_subext, MASK_ZIFENCEI},
1202
1203   {"zawrs", &gcc_options::x_riscv_za_subext, MASK_ZAWRS},
1204
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},
1209
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},
1214
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},
1225
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},
1229
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},
1235
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},
1246
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},
1259
1260   {"zfhmin",    &gcc_options::x_riscv_zf_subext, MASK_ZFHMIN},
1261   {"zfh",       &gcc_options::x_riscv_zf_subext, MASK_ZFH},
1262
1263   {"zmmul", &gcc_options::x_riscv_zm_subext, MASK_ZMMUL},
1264
1265   {"svinval", &gcc_options::x_riscv_sv_subext, MASK_SVINVAL},
1266   {"svnapot", &gcc_options::x_riscv_sv_subext, MASK_SVNAPOT},
1267
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},
1280
1281   {NULL, NULL, 0}
1282 };
1283
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.  */
1286
1287 void
1288 riscv_parse_arch_string (const char *isa,
1289                          struct gcc_options *opts,
1290                          location_t loc)
1291 {
1292   riscv_subset_list *subset_list;
1293   subset_list = riscv_subset_list::parse (isa, loc);
1294   if (!subset_list)
1295     return;
1296
1297   if (opts)
1298     {
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;
1305
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;
1310
1311
1312       for (arch_ext_flag_tab = &riscv_ext_flag_table[0];
1313            arch_ext_flag_tab->ext;
1314            ++arch_ext_flag_tab)
1315         {
1316           if (subset_list->lookup (arch_ext_flag_tab->ext))
1317             opts->*arch_ext_flag_tab->var_ref |= arch_ext_flag_tab->mask;
1318         }
1319     }
1320
1321   if (current_subset_list)
1322     delete current_subset_list;
1323
1324   current_subset_list = subset_list;
1325 }
1326
1327 /* Return the riscv_cpu_info entry for CPU, NULL if not found.  */
1328
1329 const riscv_cpu_info *
1330 riscv_find_cpu (const char *cpu)
1331 {
1332   const riscv_cpu_info *cpu_info = &riscv_cpu_tables[0];
1333   for (;cpu_info->name != NULL; ++cpu_info)
1334     {
1335       const char *name = cpu_info->name;
1336       if (strcmp (cpu, name) == 0)
1337         return cpu_info;
1338     }
1339   return NULL;
1340 }
1341
1342 /* Implement TARGET_HANDLE_OPTION.  */
1343
1344 static bool
1345 riscv_handle_option (struct gcc_options *opts,
1346                      struct gcc_options *opts_set ATTRIBUTE_UNUSED,
1347                      const struct cl_decoded_option *decoded,
1348                      location_t loc)
1349 {
1350   switch (decoded->opt_index)
1351     {
1352     case OPT_march_:
1353       riscv_parse_arch_string (decoded->arg, opts, loc);
1354       return true;
1355
1356     case OPT_mcpu_:
1357       if (riscv_find_cpu (decoded->arg) == NULL)
1358         error_at (loc, "%<-mcpu=%s%>: unknown CPU",
1359                   decoded->arg);
1360       return true;
1361
1362     default:
1363       return true;
1364     }
1365 }
1366
1367 /* Expand arch string with implied extensions.  */
1368
1369 const char *
1370 riscv_expand_arch (int argc ATTRIBUTE_UNUSED,
1371                    const char **argv)
1372 {
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);
1377   if (arch.length())
1378     return xasprintf ("-march=%s", arch.c_str());
1379   else
1380     return "";
1381 }
1382
1383 /* Expand default -mtune option from -mcpu option, use default --with-tune value
1384    if -mcpu don't have valid value.  */
1385
1386 const char *
1387 riscv_default_mtune (int argc, const char **argv)
1388 {
1389   gcc_assert (argc == 2);
1390   const riscv_cpu_info *cpu = riscv_find_cpu (argv[0]);
1391   const char *default_mtune = argv[1];
1392   if (cpu)
1393     return cpu->tune;
1394   else
1395     return default_mtune;
1396 }
1397
1398 /* Expand arch string with implied extensions from -mcpu option.  */
1399
1400 const char *
1401 riscv_expand_arch_from_cpu (int argc ATTRIBUTE_UNUSED,
1402                             const char **argv)
1403 {
1404   gcc_assert (argc > 0 && argc <= 2);
1405   const char *default_arch_str = NULL;
1406   const char *arch_str = NULL;
1407   if (argc >= 2)
1408     default_arch_str = argv[1];
1409
1410   const riscv_cpu_info *cpu = riscv_find_cpu (argv[0]);
1411
1412   if (cpu == NULL)
1413     {
1414       if (default_arch_str == NULL)
1415         return "";
1416       else
1417         arch_str = default_arch_str;
1418     }
1419   else
1420     arch_str = cpu->arch;
1421
1422   location_t loc = UNKNOWN_LOCATION;
1423
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());
1427 }
1428
1429 /* Report error if not found suitable multilib.  */
1430 const char *
1431 riscv_multi_lib_check (int argc ATTRIBUTE_UNUSED,
1432                        const char **argv ATTRIBUTE_UNUSED)
1433 {
1434   if (riscv_no_matched_multi_lib)
1435     fatal_error (
1436       input_location,
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 ());
1440
1441   return "";
1442 }
1443
1444 /* We only override this in bare-metal toolchain.  */
1445 #ifdef RISCV_USE_CUSTOMISED_MULTI_LIB
1446
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.  */
1450
1451 static const char *
1452 find_last_appear_switch (
1453   const struct switchstr *switches,
1454   int n_switches,
1455   const char *prefix)
1456 {
1457   int i;
1458   size_t len = strlen (prefix);
1459
1460   for (i = 0; i < n_switches; ++i)
1461     {
1462       const struct switchstr *this_switch = &switches[n_switches - i - 1];
1463
1464       if (this_switch->live_cond & SWITCH_FALSE)
1465         continue;
1466
1467       if (strncmp (this_switch->part1, prefix, len) == 0)
1468         return this_switch->part1 + len;
1469     }
1470
1471   return NULL;
1472 }
1473
1474 /* Utils functions to check STR is start with PREFIX or not.  */
1475
1476 static bool
1477 prefixed_with (const std::string &str, const char *prefix)
1478 {
1479   return strncmp (prefix, str.c_str (), strlen (prefix)) == 0;
1480 }
1481
1482 /* Parse the path and cond string into riscv_multi_lib_info_t, return false
1483    if parsing failed. */
1484
1485 bool
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)
1490 {
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;
1494   if (path == ".")
1495     {
1496       multi_lib_info->arch_str = default_arch_str;
1497       multi_lib_info->abi_str = default_abi_str;
1498     }
1499   else
1500     {
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=");
1507
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)
1512         return false;
1513     }
1514
1515   multi_lib_info->subset_list =
1516     riscv_subset_list::parse (multi_lib_info->arch_str.c_str (), input_location);
1517
1518   return true;
1519 }
1520
1521 /* Checking ARG is not appeared in SWITCHES if NOT_ARG is set or
1522    ARG is appeared if NOT_ARG is not set.  */
1523
1524 static bool
1525 riscv_check_cond (
1526   const struct switchstr *switches,
1527   int n_switches,
1528   const std::string &arg,
1529   bool not_arg)
1530 {
1531   int i;
1532   for (i = 0; i < n_switches; ++i)
1533     {
1534       const struct switchstr *this_switch = &switches[n_switches - i - 1];
1535
1536       if ((this_switch->live_cond & SWITCH_IGNORE) != 0)
1537         continue;
1538
1539       if (this_switch->live_cond & SWITCH_FALSE)
1540         continue;
1541
1542       /* ARG should not appear if NOT_ARG is set.  */
1543       if (arg == this_switch->part1)
1544         return not_arg ? false : true;
1545     }
1546
1547   /* Not found ARG? that's ok if NOT_ARG is not set.  */
1548   return not_arg ? true : false;
1549 }
1550
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.   */
1553
1554 static int
1555 riscv_check_conds (
1556   const struct switchstr *switches,
1557   int n_switches,
1558   int match_score,
1559   const std::vector<std::string> &conds)
1560 {
1561   bool not_arg;
1562   bool ok;
1563   int ok_count = 0;
1564   std::vector<std::string>::const_iterator itr;
1565   const char *checking_arg;
1566
1567   if (match_score == 0)
1568     return 0;
1569
1570   for (itr = conds.begin (); itr != conds.end (); ++itr)
1571     {
1572       /* We'll check march= and mabi= in other place.  */
1573       if (prefixed_with (*itr, "march=") || prefixed_with (*itr, "mabi="))
1574         continue;
1575
1576       checking_arg = itr->c_str ();
1577       if (checking_arg[0] == '!')
1578         {
1579           not_arg = true;
1580           /* Skip '!'. */
1581           checking_arg = checking_arg + 1;
1582         }
1583       else
1584         not_arg = false;
1585
1586       ok = riscv_check_cond (switches, n_switches, checking_arg, not_arg);
1587
1588       if (!ok)
1589         return -1;
1590
1591       ok_count++;
1592     }
1593
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
1596      list. */
1597   return match_score + ok_count * 100;
1598 }
1599
1600 /* Implement TARGET_COMPUTE_MULTILIB.  */
1601 static const char *
1602 riscv_compute_multilib (
1603   const struct switchstr *switches,
1604   int n_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)
1611 {
1612   const char *p;
1613   const char *this_path;
1614   size_t this_path_len;
1615   bool result;
1616   riscv_no_matched_multi_lib = false;
1617   riscv_subset_list *subset_list = NULL;
1618
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;
1623
1624   /* Already found suitable, multi-lib, just use that.  */
1625   if (multilib_dir != NULL)
1626     return multilib_dir;
1627
1628   /* Find march.  */
1629   riscv_current_arch_str =
1630     find_last_appear_switch (switches, n_switches, "march=");
1631   /* Find mabi.  */
1632   riscv_current_abi_str =
1633     find_last_appear_switch (switches, n_switches, "mabi=");
1634
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;
1639
1640   subset_list = riscv_subset_list::parse (riscv_current_arch_str.c_str (),
1641                                           input_location);
1642
1643   /* Failed to parse -march, fallback to using what gcc use.  */
1644   if (subset_list == NULL)
1645     return multilib_dir;
1646
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;
1650
1651   while (*p != '\0')
1652     {
1653       /* Ignore newlines.  */
1654       if (*p == '\n')
1655         {
1656           ++p;
1657           continue;
1658         }
1659
1660       /* Format of each multilib:
1661          <path> <opt1> <opt2> ... <optN>;  */
1662       /* Get the path.  */
1663       this_path = p;
1664       while (*p != ' ')
1665         {
1666           if (*p == '\0')
1667             {
1668               fatal_error (input_location, "multilib select %qs %qs is invalid",
1669                            multilib_select, multilib_reuse);
1670             }
1671           ++p;
1672         }
1673
1674       this_path_len = p - this_path;
1675       multilib_info.path = std::string (this_path, this_path_len);
1676
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"].  */
1681       while (*p != ';')
1682         {
1683           option_cond = "";
1684           /* Skip space.  */
1685           while (*p == ' ') p++;
1686
1687           while (*p && *p != ' ' && *p != ';')
1688               option_cond.push_back (*p++);
1689
1690           /* Ignore `!march=` and `!mabi=`, we will handle march and mabi
1691              later. */
1692           if (option_cond.size ()
1693               && !prefixed_with (option_cond, "!march=")
1694               && !prefixed_with (option_cond, "!mabi="))
1695             option_conds.push_back (option_cond);
1696         }
1697
1698       result =
1699         riscv_multi_lib_info_t::parse (
1700           &multilib_info,
1701           std::string (this_path, this_path_len),
1702           option_conds);
1703
1704       if (result)
1705         multilib_infos.push_back (multilib_info);
1706
1707       p++;
1708     }
1709
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)
1717     {
1718       /* Check ABI is same first.  */
1719       if (riscv_current_abi_str != multilib_infos[i].abi_str)
1720         continue;
1721
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);
1725
1726       /* Checking other cond in the multi-lib setting.  */
1727       match_score = riscv_check_conds (switches,
1728                                        n_switches,
1729                                        match_score,
1730                                        multilib_infos[i].conds);
1731
1732       /* Record highest match score multi-lib setting.  */
1733       if (match_score > max_match_score)
1734         {
1735           best_match_multi_lib = i;
1736           max_match_score = match_score;
1737         }
1738     }
1739
1740   if (best_match_multi_lib == -1)
1741     {
1742       riscv_no_matched_multi_lib = true;
1743       return multilib_dir;
1744     }
1745   else
1746     return xstrdup (multilib_infos[best_match_multi_lib].path.c_str ());
1747 }
1748
1749 #undef TARGET_COMPUTE_MULTILIB
1750 #define TARGET_COMPUTE_MULTILIB riscv_compute_multilib
1751 #endif
1752
1753 vec<const char *>
1754 riscv_get_valid_option_values (int option_code,
1755                                const char *prefix ATTRIBUTE_UNUSED)
1756 {
1757   vec<const char *> v;
1758   v.create (0);
1759   opt_code opt = (opt_code) option_code;
1760
1761   switch (opt)
1762     {
1763     case OPT_mtune_:
1764       {
1765         const char **tune = &riscv_tunes[0];
1766         for (;*tune; ++tune)
1767           v.safe_push (*tune);
1768
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);
1772       }
1773       break;
1774     case OPT_mcpu_:
1775       {
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);
1779       }
1780       break;
1781     default:
1782       break;
1783     }
1784
1785   return v;
1786 }
1787
1788 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
1789 static const struct default_options riscv_option_optimization_table[] =
1790   {
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},
1796 #endif
1797     { OPT_LEVELS_NONE, 0, NULL, 0 }
1798   };
1799
1800 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1801 #define TARGET_OPTION_OPTIMIZATION_TABLE riscv_option_optimization_table
1802
1803 #undef TARGET_HANDLE_OPTION
1804 #define TARGET_HANDLE_OPTION riscv_handle_option
1805
1806 #undef  TARGET_GET_VALID_OPTION_VALUES
1807 #define TARGET_GET_VALID_OPTION_VALUES riscv_get_valid_option_values
1808
1809 struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;