Home | History | Annotate | Line # | Download | only in riscv
riscv-common.cc revision 1.1
      1 /* Common hooks for RISC-V.
      2    Copyright (C) 2016-2022 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 
     22 #define INCLUDE_STRING
     23 #include "config.h"
     24 #include "system.h"
     25 #include "coretypes.h"
     26 #include "tm.h"
     27 #include "common/common-target.h"
     28 #include "common/common-target-def.h"
     29 #include "opts.h"
     30 #include "flags.h"
     31 #include "diagnostic-core.h"
     32 #include "config/riscv/riscv-protos.h"
     33 #include "config/riscv/riscv-subset.h"
     34 
     35 #ifdef  TARGET_BIG_ENDIAN_DEFAULT
     36 #undef  TARGET_DEFAULT_TARGET_FLAGS
     37 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
     38 #endif
     39 
     40 /* Type for implied ISA info.  */
     41 struct riscv_implied_info_t
     42 {
     43   const char *ext;
     44   const char *implied_ext;
     45 };
     46 
     47 /* Implied ISA info, must end with NULL sentinel.  */
     48 static const riscv_implied_info_t riscv_implied_info[] =
     49 {
     50   {"d", "f"},
     51   {"f", "zicsr"},
     52   {"d", "zicsr"},
     53   {"zk", "zkn"},
     54   {"zk", "zkr"},
     55   {"zk", "zkt"},
     56   {"zkn", "zbkb"},
     57   {"zkn", "zbkc"},
     58   {"zkn", "zbkx"},
     59   {"zkn", "zkne"},
     60   {"zkn", "zknd"},
     61   {"zkn", "zknh"},
     62   {"zks", "zbkb"},
     63   {"zks", "zbkc"},
     64   {"zks", "zbkx"},
     65   {"zks", "zksed"},
     66   {"zks", "zksh"},
     67 
     68   {"v", "zvl128b"},
     69   {"v", "zve64d"},
     70 
     71   {"zve32f", "f"},
     72   {"zve64f", "f"},
     73   {"zve64d", "d"},
     74 
     75   {"zve32x", "zvl32b"},
     76   {"zve32f", "zve32x"},
     77   {"zve32f", "zvl32b"},
     78 
     79   {"zve64x", "zve32x"},
     80   {"zve64x", "zvl64b"},
     81   {"zve64f", "zve32f"},
     82   {"zve64f", "zve64x"},
     83   {"zve64f", "zvl64b"},
     84   {"zve64d", "zve64f"},
     85   {"zve64d", "zvl64b"},
     86 
     87   {"zvl64b", "zvl32b"},
     88   {"zvl128b", "zvl64b"},
     89   {"zvl256b", "zvl128b"},
     90   {"zvl512b", "zvl256b"},
     91   {"zvl1024b", "zvl512b"},
     92   {"zvl2048b", "zvl1024b"},
     93   {"zvl4096b", "zvl2048b"},
     94   {"zvl8192b", "zvl4096b"},
     95   {"zvl16384b", "zvl8192b"},
     96   {"zvl32768b", "zvl16384b"},
     97   {"zvl65536b", "zvl32768b"},
     98 
     99   {NULL, NULL}
    100 };
    101 
    102 /* This structure holds version information for specific ISA version.  */
    103 
    104 struct riscv_ext_version
    105 {
    106   const char *name;
    107   enum riscv_isa_spec_class isa_spec_class;
    108   int major_version;
    109   int minor_version;
    110 };
    111 
    112 /* All standard extensions defined in all supported ISA spec.  */
    113 static const struct riscv_ext_version riscv_ext_version_table[] =
    114 {
    115   /* name, ISA spec, major version, minor_version.  */
    116   {"e", ISA_SPEC_CLASS_20191213, 1, 9},
    117   {"e", ISA_SPEC_CLASS_20190608, 1, 9},
    118   {"e", ISA_SPEC_CLASS_2P2,      1, 9},
    119 
    120   {"i", ISA_SPEC_CLASS_20191213, 2, 1},
    121   {"i", ISA_SPEC_CLASS_20190608, 2, 1},
    122   {"i", ISA_SPEC_CLASS_2P2,      2, 0},
    123 
    124   {"m", ISA_SPEC_CLASS_20191213, 2, 0},
    125   {"m", ISA_SPEC_CLASS_20190608, 2, 0},
    126   {"m", ISA_SPEC_CLASS_2P2,      2, 0},
    127 
    128   {"a", ISA_SPEC_CLASS_20191213, 2, 1},
    129   {"a", ISA_SPEC_CLASS_20190608, 2, 0},
    130   {"a", ISA_SPEC_CLASS_2P2,      2, 0},
    131 
    132   {"f", ISA_SPEC_CLASS_20191213, 2, 2},
    133   {"f", ISA_SPEC_CLASS_20190608, 2, 2},
    134   {"f", ISA_SPEC_CLASS_2P2,      2, 0},
    135 
    136   {"d", ISA_SPEC_CLASS_20191213, 2, 2},
    137   {"d", ISA_SPEC_CLASS_20190608, 2, 2},
    138   {"d", ISA_SPEC_CLASS_2P2,      2, 0},
    139 
    140   {"c", ISA_SPEC_CLASS_20191213, 2, 0},
    141   {"c", ISA_SPEC_CLASS_20190608, 2, 0},
    142   {"c", ISA_SPEC_CLASS_2P2,      2, 0},
    143 
    144   {"v",       ISA_SPEC_CLASS_NONE, 1, 0},
    145 
    146   {"zicsr", ISA_SPEC_CLASS_20191213, 2, 0},
    147   {"zicsr", ISA_SPEC_CLASS_20190608, 2, 0},
    148 
    149   {"zifencei", ISA_SPEC_CLASS_20191213, 2, 0},
    150   {"zifencei", ISA_SPEC_CLASS_20190608, 2, 0},
    151 
    152   {"zba", ISA_SPEC_CLASS_NONE, 1, 0},
    153   {"zbb", ISA_SPEC_CLASS_NONE, 1, 0},
    154   {"zbc", ISA_SPEC_CLASS_NONE, 1, 0},
    155   {"zbs", ISA_SPEC_CLASS_NONE, 1, 0},
    156 
    157   {"zbkb",  ISA_SPEC_CLASS_NONE, 1, 0},
    158   {"zbkc",  ISA_SPEC_CLASS_NONE, 1, 0},
    159   {"zbkx",  ISA_SPEC_CLASS_NONE, 1, 0},
    160   {"zkne",  ISA_SPEC_CLASS_NONE, 1, 0},
    161   {"zknd",  ISA_SPEC_CLASS_NONE, 1, 0},
    162   {"zknh",  ISA_SPEC_CLASS_NONE, 1, 0},
    163   {"zkr",   ISA_SPEC_CLASS_NONE, 1, 0},
    164   {"zksed", ISA_SPEC_CLASS_NONE, 1, 0},
    165   {"zksh",  ISA_SPEC_CLASS_NONE, 1, 0},
    166   {"zkt",   ISA_SPEC_CLASS_NONE, 1, 0},
    167 
    168   {"zk",    ISA_SPEC_CLASS_NONE, 1, 0},
    169   {"zkn",   ISA_SPEC_CLASS_NONE, 1, 0},
    170   {"zks",   ISA_SPEC_CLASS_NONE, 1, 0},
    171 
    172   {"zve32x", ISA_SPEC_CLASS_NONE, 1, 0},
    173   {"zve32f", ISA_SPEC_CLASS_NONE, 1, 0},
    174   {"zve32d", ISA_SPEC_CLASS_NONE, 1, 0},
    175   {"zve64x", ISA_SPEC_CLASS_NONE, 1, 0},
    176   {"zve64f", ISA_SPEC_CLASS_NONE, 1, 0},
    177   {"zve64d", ISA_SPEC_CLASS_NONE, 1, 0},
    178 
    179   {"zvl32b", ISA_SPEC_CLASS_NONE, 1, 0},
    180   {"zvl64b", ISA_SPEC_CLASS_NONE, 1, 0},
    181   {"zvl128b", ISA_SPEC_CLASS_NONE, 1, 0},
    182   {"zvl256b", ISA_SPEC_CLASS_NONE, 1, 0},
    183   {"zvl512b", ISA_SPEC_CLASS_NONE, 1, 0},
    184   {"zvl1024b", ISA_SPEC_CLASS_NONE, 1, 0},
    185   {"zvl2048b", ISA_SPEC_CLASS_NONE, 1, 0},
    186   {"zvl4096b", ISA_SPEC_CLASS_NONE, 1, 0},
    187   {"zvl8192b", ISA_SPEC_CLASS_NONE, 1, 0},
    188   {"zvl16384b", ISA_SPEC_CLASS_NONE, 1, 0},
    189   {"zvl32768b", ISA_SPEC_CLASS_NONE, 1, 0},
    190   {"zvl65536b", ISA_SPEC_CLASS_NONE, 1, 0},
    191 
    192   /* Terminate the list.  */
    193   {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
    194 };
    195 
    196 /* Combine extensions defined in this table  */
    197 static const struct riscv_ext_version riscv_combine_info[] =
    198 {
    199   {"zk",  ISA_SPEC_CLASS_NONE, 1, 0},
    200   {"zkn",  ISA_SPEC_CLASS_NONE, 1, 0},
    201   {"zks",  ISA_SPEC_CLASS_NONE, 1, 0},
    202   /* Terminate the list.  */
    203   {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
    204 };
    205 
    206 static const riscv_cpu_info riscv_cpu_tables[] =
    207 {
    208 #define RISCV_CORE(CORE_NAME, ARCH, TUNE) \
    209     {CORE_NAME, ARCH, TUNE},
    210 #include "../../../config/riscv/riscv-cores.def"
    211     {NULL, NULL, NULL}
    212 };
    213 
    214 static const char *riscv_supported_std_ext (void);
    215 
    216 static riscv_subset_list *current_subset_list = NULL;
    217 
    218 const riscv_subset_list *riscv_current_subset_list ()
    219 {
    220   return current_subset_list;
    221 }
    222 
    223 riscv_subset_t::riscv_subset_t ()
    224   : name (), major_version (0), minor_version (0), next (NULL),
    225     explicit_version_p (false), implied_p (false)
    226 {
    227 }
    228 
    229 riscv_subset_list::riscv_subset_list (const char *arch, location_t loc)
    230   : m_arch (arch), m_loc (loc), m_head (NULL), m_tail (NULL), m_xlen (0)
    231 {
    232 }
    233 
    234 riscv_subset_list::~riscv_subset_list ()
    235 {
    236   if (!m_head)
    237     return;
    238 
    239   riscv_subset_t *item = this->m_head;
    240   while (item != NULL)
    241     {
    242       riscv_subset_t *next = item->next;
    243       delete item;
    244       item = next;
    245     }
    246 }
    247 
    248 /* Get the rank for single-letter subsets, lower value meaning higher
    249    priority.  */
    250 
    251 static int
    252 single_letter_subset_rank (char ext)
    253 {
    254   int rank;
    255 
    256   switch (ext)
    257     {
    258     case 'i':
    259       return 0;
    260     case 'e':
    261       return 1;
    262     default:
    263       break;
    264     }
    265 
    266   const char *all_ext = riscv_supported_std_ext ();
    267   const char *ext_pos = strchr (all_ext, ext);
    268   if (ext_pos == NULL)
    269     /* If got an unknown extension letter, then give it an alphabetical
    270        order, but after all known standard extension.  */
    271     rank = strlen (all_ext) + ext - 'a';
    272   else
    273     rank = (int)(ext_pos - all_ext) + 2 /* e and i has higher rank.  */;
    274 
    275   return rank;
    276 }
    277 
    278 /* Get the rank for multi-letter subsets, lower value meaning higher
    279    priority.  */
    280 
    281 static int
    282 multi_letter_subset_rank (const std::string &subset)
    283 {
    284   gcc_assert (subset.length () >= 2);
    285   int high_order = -1;
    286   int low_order = 0;
    287   /* The order between multi-char extensions: s -> h -> z -> x.  */
    288   char multiletter_class = subset[0];
    289   switch (multiletter_class)
    290     {
    291     case 's':
    292       high_order = 0;
    293       break;
    294     case 'h':
    295       high_order = 1;
    296       break;
    297     case 'z':
    298       high_order = 2;
    299       break;
    300     case 'x':
    301       high_order = 3;
    302       break;
    303     default:
    304       gcc_unreachable ();
    305       return -1;
    306     }
    307 
    308   if (multiletter_class == 'z')
    309     /* Order for z extension on spec: If multiple "Z" extensions are named, they
    310        should be ordered first by category, then alphabetically within a
    311        category - for example, "Zicsr_Zifencei_Zam". */
    312     low_order = single_letter_subset_rank (subset[1]);
    313   else
    314     low_order = 0;
    315 
    316   return (high_order << 8) + low_order;
    317 }
    318 
    319 /* subset compare
    320 
    321   Returns an integral value indicating the relationship between the subsets:
    322   Return value  indicates
    323   -1            B has higher order than A.
    324   0             A and B are same subset.
    325   1             A has higher order than B.
    326 
    327 */
    328 
    329 static int
    330 subset_cmp (const std::string &a, const std::string &b)
    331 {
    332   if (a == b)
    333     return 0;
    334 
    335   size_t a_len = a.length ();
    336   size_t b_len = b.length ();
    337 
    338   /* Single-letter extension always get higher order than
    339      multi-letter extension.  */
    340   if (a_len == 1 && b_len != 1)
    341     return 1;
    342 
    343   if (a_len != 1 && b_len == 1)
    344     return -1;
    345 
    346   if (a_len == 1 && b_len == 1)
    347     {
    348       int rank_a = single_letter_subset_rank (a[0]);
    349       int rank_b = single_letter_subset_rank (b[0]);
    350 
    351       if (rank_a < rank_b)
    352 	return 1;
    353       else
    354 	return -1;
    355     }
    356   else
    357     {
    358       int rank_a = multi_letter_subset_rank(a);
    359       int rank_b = multi_letter_subset_rank(b);
    360 
    361       /* Using alphabetical/lexicographical order if they have same rank.  */
    362       if (rank_a == rank_b)
    363 	/* The return value of strcmp has opposite meaning.  */
    364 	return -strcmp (a.c_str (), b.c_str ());
    365       else
    366 	return (rank_a < rank_b) ? 1 : -1;
    367     }
    368 }
    369 
    370 /* Add new subset to list.  */
    371 
    372 void
    373 riscv_subset_list::add (const char *subset, int major_version,
    374 			int minor_version, bool explicit_version_p,
    375 			bool implied_p)
    376 {
    377   riscv_subset_t *ext = lookup (subset);
    378 
    379   if (ext)
    380     {
    381       if (ext->implied_p)
    382 	{
    383 	  /* We won't add impiled `ext` if it already in list. */
    384 	  gcc_assert (!implied_p);
    385 	  ext->implied_p = implied_p;
    386 	  ext->major_version = major_version;
    387 	  ext->minor_version = minor_version;
    388 	}
    389       else
    390 	error_at (
    391 	  m_loc,
    392 	  "%<-march=%s%>: extension %qs appear more than one time",
    393 	  m_arch,
    394 	  subset);
    395 
    396       return;
    397     }
    398 
    399   riscv_subset_t *s = new riscv_subset_t ();
    400   riscv_subset_t *itr;
    401 
    402   if (m_head == NULL)
    403     m_head = s;
    404 
    405   s->name = subset;
    406   s->major_version = major_version;
    407   s->minor_version = minor_version;
    408   s->explicit_version_p = explicit_version_p;
    409   s->implied_p = implied_p;
    410   s->next = NULL;
    411 
    412   if (m_tail == NULL)
    413     {
    414       m_tail = s;
    415       return;
    416     }
    417 
    418   /* e, i or g should be first subext, never come here.  */
    419   gcc_assert (subset[0] != 'e'
    420 	      && subset[0] != 'i'
    421 	      && subset[0] != 'g');
    422 
    423   if (m_tail == m_head)
    424     {
    425       gcc_assert (m_head->next == NULL);
    426       m_head->next = s;
    427       m_tail = s;
    428       return;
    429     }
    430 
    431   gcc_assert (m_head->next != NULL);
    432 
    433   /* Subset list must in canonical order, but implied subset won't
    434      add in canonical order.  */
    435   for (itr = m_head; itr->next != NULL; itr = itr->next)
    436     {
    437       riscv_subset_t *next = itr->next;
    438       int cmp = subset_cmp (s->name, next->name);
    439       gcc_assert (cmp != 0);
    440 
    441       if (cmp > 0)
    442 	{
    443 	  s->next = next;
    444 	  itr->next = s;
    445 	  return;
    446 	}
    447     }
    448 
    449   /* Insert at tail of the list.  */
    450   itr->next = s;
    451   m_tail = s;
    452 }
    453 
    454 static void
    455 get_default_version (const char *ext,
    456 		     unsigned int *major_version,
    457 		     unsigned int *minor_version)
    458 {
    459   const riscv_ext_version *ext_ver;
    460   for (ext_ver = &riscv_ext_version_table[0];
    461        ext_ver->name != NULL;
    462        ++ext_ver)
    463     if (strcmp (ext, ext_ver->name) == 0)
    464       {
    465 	if ((ext_ver->isa_spec_class == riscv_isa_spec) ||
    466 	    (ext_ver->isa_spec_class == ISA_SPEC_CLASS_NONE))
    467 	  {
    468 	    *major_version = ext_ver->major_version;
    469 	    *minor_version = ext_ver->minor_version;
    470 	    return;
    471 	  }
    472       }
    473 
    474   /* Not found version info.  */
    475   *major_version = 0;
    476   *minor_version = 0;
    477 }
    478 
    479 /* Add new subset to list, but using default version from ISA spec version.  */
    480 
    481 void
    482 riscv_subset_list::add (const char *subset, bool implied_p)
    483 {
    484   unsigned int major_version = 0, minor_version = 0;
    485 
    486   get_default_version (subset, &major_version, &minor_version);
    487 
    488   add (subset, major_version, minor_version, false, implied_p);
    489 }
    490 
    491 /* Convert subset info to string with explicit version info,
    492    VERSION_P to determine append version info or not.  */
    493 
    494 std::string
    495 riscv_subset_list::to_string (bool version_p) const
    496 {
    497   std::ostringstream oss;
    498   oss << "rv" << m_xlen;
    499 
    500   bool first = true;
    501   riscv_subset_t *subset;
    502 
    503   bool skip_zifencei = false;
    504   bool skip_zicsr = false;
    505   bool i2p0 = false;
    506 
    507   /* For RISC-V ISA version 2.2 or earlier version, zicsr and zifencei is
    508      included in the base ISA.  */
    509   if (riscv_isa_spec == ISA_SPEC_CLASS_2P2)
    510     {
    511       skip_zifencei = true;
    512       skip_zicsr = true;
    513     }
    514 
    515   for (subset = m_head; subset != NULL; subset = subset->next)
    516     if (subset->name == "i")
    517       {
    518 	i2p0 = subset->major_version == 2 && subset->minor_version == 0;
    519 	break;
    520       }
    521 
    522 #ifndef HAVE_AS_MISA_SPEC
    523   /* Skip since older binutils doesn't recognize zicsr.  */
    524   skip_zicsr = true;
    525 #endif
    526 #ifndef HAVE_AS_MARCH_ZIFENCEI
    527   /* Skip since older binutils doesn't recognize zifencei, we made
    528      a mistake in that binutils 2.35 supports zicsr but not zifencei.  */
    529   skip_zifencei = true;
    530 #endif
    531 
    532   for (subset = m_head; subset != NULL; subset = subset->next)
    533     {
    534       if (((subset->implied_p && skip_zifencei) || i2p0) &&
    535 	  subset->name == "zifencei")
    536 	continue;
    537 
    538       if (((subset->implied_p && skip_zicsr) || i2p0) &&
    539 	  subset->name == "zicsr")
    540 	continue;
    541 
    542       /* For !version_p, we only separate extension with underline for
    543 	 multi-letter extension.  */
    544       if (!first &&
    545 	  (version_p
    546 	   || subset->explicit_version_p
    547 	   || subset->name.length() > 1))
    548 	oss << '_';
    549       first = false;
    550 
    551       oss << subset->name;
    552 
    553       /* Let binutils decide the extension version if we don't know.  */
    554       if ((version_p || subset->explicit_version_p) &&
    555 	  (subset->major_version != 0 || subset->minor_version != 0))
    556 	oss  << subset->major_version
    557 	     << 'p'
    558 	     << subset->minor_version;
    559     }
    560 
    561   return oss.str ();
    562 }
    563 
    564 /* Find subset in list with version checking, return NULL if not found.
    565    major/minor version checking can be ignored if major_version/minor_version
    566    is RISCV_DONT_CARE_VERSION.  */
    567 
    568 riscv_subset_t *
    569 riscv_subset_list::lookup (const char *subset, int major_version,
    570 			   int minor_version) const
    571 {
    572   riscv_subset_t *s;
    573 
    574   for (s = m_head; s != NULL; s = s->next)
    575     if (strcasecmp (s->name.c_str (), subset) == 0)
    576       {
    577 	if ((major_version != RISCV_DONT_CARE_VERSION)
    578 	    && (s->major_version != major_version))
    579 	  return NULL;
    580 
    581 	if ((minor_version != RISCV_DONT_CARE_VERSION)
    582 	    && (s->minor_version != minor_version))
    583 	  return NULL;
    584 
    585 	return s;
    586       }
    587 
    588   return s;
    589 }
    590 
    591 /* Return string which contains all supported standard extensions in
    592    canonical order.  */
    593 
    594 static const char *
    595 riscv_supported_std_ext (void)
    596 {
    597   return "mafdqlcbjktpvn";
    598 }
    599 
    600 /* Parsing subset version.
    601 
    602    Return Value:
    603      Points to the end of version
    604 
    605    Arguments:
    606      `ext`: This extension.
    607      `p`: Current parsing position.
    608      `major_version`: Parsing result of major version, using
    609       default_major_version if version is not present in arch string.
    610      `minor_version`: Parsing result of minor version, set to 0 if version is
    611      not present in arch string, but set to `default_minor_version` if
    612      `major_version` using default_major_version.
    613      `std_ext_p`: True if parsing std extension.
    614      `explicit_version_p`: True if this subset is not using default version.  */
    615 
    616 const char *
    617 riscv_subset_list::parsing_subset_version (const char *ext,
    618 					   const char *p,
    619 					   unsigned *major_version,
    620 					   unsigned *minor_version,
    621 					   bool std_ext_p,
    622 					   bool *explicit_version_p)
    623 {
    624   bool major_p = true;
    625   unsigned version = 0;
    626   unsigned major = 0;
    627   unsigned minor = 0;
    628   *explicit_version_p = false;
    629 
    630   /* If we got `p`, that means we are still parsing standard extension.  */
    631   gcc_assert (std_ext_p || *p != 'p');
    632 
    633   if (*p != 'p') {
    634     for (; *p; ++p)
    635       {
    636 	if (*p == 'p')
    637 	  {
    638 	    if (!ISDIGIT (*(p+1)))
    639 	      {
    640 		error_at (m_loc, "%<-march=%s%>: expect number "
    641 			  "after %<%dp%>", m_arch, version);
    642 		return NULL;
    643 	      }
    644 	    if (!major_p)
    645 	      {
    646 		error_at (m_loc, "%<-march=%s%>: for %<%s%dp%dp?%>, version "
    647 			  "number with more than 2 level is not supported",
    648 			  m_arch, ext, major, version);
    649 		return NULL;
    650 	      }
    651 	    major = version;
    652 	    major_p = false;
    653 	    version = 0;
    654 	  }
    655 	else if (ISDIGIT (*p))
    656 	  version = (version * 10) + (*p - '0');
    657 	else
    658 	  break;
    659       }
    660   }
    661 
    662   if (major_p)
    663     major = version;
    664   else
    665     minor = version;
    666 
    667   if (major == 0 && minor == 0)
    668     get_default_version (ext, major_version, minor_version);
    669   else
    670     {
    671       *explicit_version_p = true;
    672       *major_version = major;
    673       *minor_version = minor;
    674     }
    675   return p;
    676 }
    677 
    678 /* Parsing function for standard extensions.
    679 
    680    Return Value:
    681      Points to the end of extensions.
    682 
    683    Arguments:
    684      `p`: Current parsing position.  */
    685 
    686 const char *
    687 riscv_subset_list::parse_std_ext (const char *p)
    688 {
    689   const char *all_std_exts = riscv_supported_std_ext ();
    690   const char *std_exts = all_std_exts;
    691 
    692   unsigned major_version = 0;
    693   unsigned minor_version = 0;
    694   char std_ext = '\0';
    695   bool explicit_version_p = false;
    696 
    697   /* First letter must start with i, e or g.  */
    698   switch (*p)
    699     {
    700     case 'i':
    701       p++;
    702       p = parsing_subset_version ("i", p, &major_version, &minor_version,
    703 				  /* std_ext_p= */ true, &explicit_version_p);
    704       add ("i", major_version, minor_version, explicit_version_p, false);
    705       break;
    706 
    707     case 'e':
    708       p++;
    709       p = parsing_subset_version ("e", p, &major_version, &minor_version,
    710 				  /* std_ext_p= */ true, &explicit_version_p);
    711 
    712       add ("e", major_version, minor_version, explicit_version_p, false);
    713 
    714       if (m_xlen > 32)
    715 	{
    716 	  error_at (m_loc, "%<-march=%s%>: rv%de is not a valid base ISA",
    717 		    m_arch, m_xlen);
    718 	  return NULL;
    719 	}
    720       break;
    721 
    722     case 'g':
    723       p++;
    724       p = parsing_subset_version ("g", p, &major_version, &minor_version,
    725 				  /* std_ext_p= */ true, &explicit_version_p);
    726       if (major_version != 0 || minor_version != 0)
    727 	{
    728 	  warning_at (m_loc, 0, "version of %<g%> will be omitted, please "
    729 				"specify version for individual extension");
    730 	}
    731 
    732       /* We have special rule for G, we disallow rv32gm2p but allow rv32g_zicsr
    733 	 here, basically we treating G expand to imafd and implied zicsr and
    734 	 zifencei.  */
    735 
    736       add ("i", false);
    737       add ("m", false);
    738       add ("a", false);
    739       add ("f", false);
    740       add ("d", false);
    741       add ("zicsr", true);
    742       add ("zifencei", true);
    743 
    744       break;
    745 
    746     default:
    747       error_at (m_loc, "%<-march=%s%>: first ISA subset must be %<e%>, "
    748 		"%<i%> or %<g%>", m_arch);
    749       return NULL;
    750     }
    751 
    752   while (p != NULL && *p)
    753     {
    754       char subset[2] = {0, 0};
    755 
    756       if (*p == 'x' || *p == 's' || *p == 'h' || *p == 'z')
    757 	break;
    758 
    759       if (*p == '_')
    760 	{
    761 	  p++;
    762 	  continue;
    763 	}
    764 
    765       std_ext = *p;
    766 
    767       /* Checking canonical order.  */
    768       while (*std_exts && std_ext != *std_exts)
    769 	std_exts++;
    770 
    771       if (std_ext != *std_exts)
    772 	{
    773 	  if (strchr (all_std_exts, std_ext) == NULL)
    774 	    error_at (m_loc, "%<-march=%s%>: unsupported ISA subset %<%c%>",
    775 		      m_arch, *p);
    776 	  else
    777 	    error_at (m_loc,
    778 		      "%<-march=%s%>: ISA string is not in canonical order. "
    779 		      "%<%c%>", m_arch, *p);
    780 	  return NULL;
    781 	}
    782 
    783       std_exts++;
    784 
    785       p++;
    786       subset[0] = std_ext;
    787 
    788       p = parsing_subset_version (subset, p, &major_version, &minor_version,
    789 				  /* std_ext_p= */ true, &explicit_version_p);
    790 
    791       add (subset, major_version, minor_version, explicit_version_p, false);
    792     }
    793   return p;
    794 }
    795 
    796 
    797 /* Check any implied extensions for EXT.  */
    798 void
    799 riscv_subset_list::handle_implied_ext (riscv_subset_t *ext)
    800 {
    801   const riscv_implied_info_t *implied_info;
    802   for (implied_info = &riscv_implied_info[0];
    803        implied_info->ext;
    804        ++implied_info)
    805     {
    806       if (strcmp (ext->name.c_str (), implied_info->ext) != 0)
    807 	continue;
    808 
    809       /* Skip if implied extension already present.  */
    810       if (lookup (implied_info->implied_ext))
    811 	continue;
    812 
    813       /* Version of implied extension will get from current ISA spec
    814 	 version.  */
    815       add (implied_info->implied_ext, true);
    816     }
    817 
    818   /* For RISC-V ISA version 2.2 or earlier version, zicsr and zifence is
    819      included in the base ISA.  */
    820   if (riscv_isa_spec == ISA_SPEC_CLASS_2P2)
    821     {
    822       if (lookup ("zicsr") == NULL)
    823 	add ("zicsr", true);
    824 
    825       if (lookup ("zifencei") == NULL)
    826 	add ("zifencei", true);
    827     }
    828 }
    829 
    830 /* Check any combine extensions for EXT.  */
    831 void
    832 riscv_subset_list::handle_combine_ext ()
    833 {
    834   const riscv_ext_version *combine_info;
    835   const riscv_implied_info_t *implied_info;
    836   bool is_combined = false;
    837 
    838   for (combine_info = &riscv_combine_info[0]; combine_info->name;
    839        ++combine_info)
    840     {
    841       /* Skip if combine extensions are present */
    842       if (lookup (combine_info->name))
    843 	continue;
    844 
    845       /* Find all extensions of the combine extension   */
    846       for (implied_info = &riscv_implied_info[0]; implied_info->ext;
    847 	   ++implied_info)
    848 	{
    849 	  /* Skip if implied extension don't match combine extension */
    850 	  if (strcmp (combine_info->name, implied_info->ext) != 0)
    851 	    continue;
    852 
    853 	  if (lookup (implied_info->implied_ext))
    854 	    is_combined = true;
    855 	  else
    856 	    {
    857 	      is_combined = false;
    858 	      break;
    859 	    }
    860 	}
    861 
    862       /* Add combine extensions */
    863       if (is_combined)
    864 	{
    865 	  if (lookup (combine_info->name) == NULL)
    866 	    {
    867 	      add (combine_info->name, combine_info->major_version,
    868 		   combine_info->minor_version, false, true);
    869 	    }
    870 	}
    871     }
    872 }
    873 
    874 /* Parsing function for multi-letter extensions.
    875 
    876    Return Value:
    877      Points to the end of extensions.
    878 
    879    Arguments:
    880      `p`: Current parsing position.
    881      `ext_type`: What kind of extensions, 's', 'h', 'z' or 'x'.
    882      `ext_type_str`: Full name for kind of extension.  */
    883 
    884 const char *
    885 riscv_subset_list::parse_multiletter_ext (const char *p,
    886 					  const char *ext_type,
    887 					  const char *ext_type_str)
    888 {
    889   unsigned major_version = 0;
    890   unsigned minor_version = 0;
    891   size_t ext_type_len = strlen (ext_type);
    892 
    893   while (*p)
    894     {
    895       if (*p == '_')
    896 	{
    897 	  p++;
    898 	  continue;
    899 	}
    900 
    901       if (strncmp (p, ext_type, ext_type_len) != 0)
    902 	break;
    903 
    904       char *subset = xstrdup (p);
    905       char *q = subset;
    906       const char *end_of_version;
    907       bool explicit_version_p = false;
    908       char *ext;
    909       char backup;
    910       size_t len;
    911       size_t end_of_version_pos, i;
    912       bool found_any_number = false;
    913       bool found_minor_version = false;
    914 
    915       /* Parse until end of this extension including version number.  */
    916       while (*++q != '\0' && *q != '_')
    917 	;
    918 
    919       backup = *q;
    920       *q = '\0';
    921       len = q - subset;
    922       *q = backup;
    923 
    924       end_of_version_pos = len;
    925       /* Find the begin of version string.  */
    926       for (i = len -1; i > 0; --i)
    927 	{
    928 	  if (ISDIGIT (subset[i]))
    929 	    {
    930 	      found_any_number = true;
    931 	      continue;
    932 	    }
    933 	  /* Might be version seperator, but need to check one more char,
    934 	     we only allow <major>p<minor>, so we could stop parsing if found
    935 	     any more `p`.  */
    936 	  if (subset[i] == 'p' &&
    937 	      !found_minor_version &&
    938 	      found_any_number && ISDIGIT (subset[i-1]))
    939 	    {
    940 	      found_minor_version = true;
    941 	      continue;
    942 	    }
    943 
    944 	  end_of_version_pos = i + 1;
    945 	  break;
    946 	}
    947 
    948       backup = subset[end_of_version_pos];
    949       subset[end_of_version_pos] = '\0';
    950       ext = xstrdup (subset);
    951       subset[end_of_version_pos] = backup;
    952 
    953       end_of_version
    954 	= parsing_subset_version (ext, subset + end_of_version_pos, &major_version, &minor_version,
    955 				  /* std_ext_p= */ false, &explicit_version_p);
    956       free (ext);
    957 
    958       if (end_of_version == NULL)
    959 	return NULL;
    960 
    961       subset[end_of_version_pos] = '\0';
    962 
    963       if (strlen (subset) == 1)
    964 	{
    965 	  error_at (m_loc, "%<-march=%s%>: name of %s must be more than 1 letter",
    966 		    m_arch, ext_type_str);
    967 	  free (subset);
    968 	  return NULL;
    969 	}
    970 
    971       add (subset, major_version, minor_version, explicit_version_p, false);
    972       p += end_of_version - subset;
    973       free (subset);
    974 
    975       if (*p != '\0' && *p != '_')
    976 	{
    977 	  error_at (m_loc, "%<-march=%s%>: %s must separate with %<_%>",
    978 		    m_arch, ext_type_str);
    979 	  return NULL;
    980 	}
    981     }
    982 
    983   return p;
    984 }
    985 
    986 /* Parsing arch string to subset list, return NULL if parsing failed.  */
    987 
    988 riscv_subset_list *
    989 riscv_subset_list::parse (const char *arch, location_t loc)
    990 {
    991   riscv_subset_list *subset_list = new riscv_subset_list (arch, loc);
    992   riscv_subset_t *itr;
    993   const char *p = arch;
    994   if (startswith (p, "rv32"))
    995     {
    996       subset_list->m_xlen = 32;
    997       p += 4;
    998     }
    999   else if (startswith (p, "rv64"))
   1000     {
   1001       subset_list->m_xlen = 64;
   1002       p += 4;
   1003     }
   1004   else
   1005     {
   1006       error_at (loc, "%<-march=%s%>: ISA string must begin with rv32 or rv64",
   1007 		arch);
   1008       goto fail;
   1009     }
   1010 
   1011   /* Parsing standard extension.  */
   1012   p = subset_list->parse_std_ext (p);
   1013 
   1014   if (p == NULL)
   1015     goto fail;
   1016 
   1017   /* Parsing supervisor extension.  */
   1018   p = subset_list->parse_multiletter_ext (p, "s", "supervisor extension");
   1019 
   1020   if (p == NULL)
   1021     goto fail;
   1022 
   1023   /* Parsing hypervisor extension.  */
   1024   p = subset_list->parse_multiletter_ext (p, "h", "hypervisor extension");
   1025 
   1026   if (p == NULL)
   1027     goto fail;
   1028 
   1029   /* Parsing sub-extensions.  */
   1030   p = subset_list->parse_multiletter_ext (p, "z", "sub-extension");
   1031 
   1032   if (p == NULL)
   1033     goto fail;
   1034 
   1035   /* Parsing non-standard extension.  */
   1036   p = subset_list->parse_multiletter_ext (p, "x", "non-standard extension");
   1037 
   1038   if (p == NULL)
   1039     goto fail;
   1040 
   1041   if (*p != '\0')
   1042     {
   1043       error_at (loc, "%<-march=%s%>: unexpected ISA string at end: %qs",
   1044                arch, p);
   1045       goto fail;
   1046     }
   1047 
   1048   for (itr = subset_list->m_head; itr != NULL; itr = itr->next)
   1049     {
   1050       subset_list->handle_implied_ext (itr);
   1051     }
   1052 
   1053   subset_list->handle_combine_ext ();
   1054 
   1055   return subset_list;
   1056 
   1057 fail:
   1058   delete subset_list;
   1059   return NULL;
   1060 }
   1061 
   1062 /* Return the current arch string.  */
   1063 
   1064 std::string
   1065 riscv_arch_str (bool version_p)
   1066 {
   1067   if (current_subset_list)
   1068     return current_subset_list->to_string (version_p);
   1069   else
   1070     return std::string();
   1071 }
   1072 
   1073 /* Type for pointer to member of gcc_options.  */
   1074 typedef int (gcc_options::*opt_var_ref_t);
   1075 
   1076 /* Types for recording extension to internal flag.  */
   1077 struct riscv_ext_flag_table_t {
   1078   const char *ext;
   1079   opt_var_ref_t var_ref;
   1080   int mask;
   1081 };
   1082 
   1083 /* Mapping table between extension to internal flag.  */
   1084 static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
   1085 {
   1086   {"e", &gcc_options::x_target_flags, MASK_RVE},
   1087   {"m", &gcc_options::x_target_flags, MASK_MUL},
   1088   {"a", &gcc_options::x_target_flags, MASK_ATOMIC},
   1089   {"f", &gcc_options::x_target_flags, MASK_HARD_FLOAT},
   1090   {"d", &gcc_options::x_target_flags, MASK_DOUBLE_FLOAT},
   1091   {"c", &gcc_options::x_target_flags, MASK_RVC},
   1092   {"v", &gcc_options::x_target_flags, MASK_VECTOR},
   1093 
   1094   {"zicsr",    &gcc_options::x_riscv_zi_subext, MASK_ZICSR},
   1095   {"zifencei", &gcc_options::x_riscv_zi_subext, MASK_ZIFENCEI},
   1096 
   1097   {"zba",    &gcc_options::x_riscv_zb_subext, MASK_ZBA},
   1098   {"zbb",    &gcc_options::x_riscv_zb_subext, MASK_ZBB},
   1099   {"zbc",    &gcc_options::x_riscv_zb_subext, MASK_ZBC},
   1100   {"zbs",    &gcc_options::x_riscv_zb_subext, MASK_ZBS},
   1101 
   1102   {"zbkb",   &gcc_options::x_riscv_zk_subext, MASK_ZBKB},
   1103   {"zbkc",   &gcc_options::x_riscv_zk_subext, MASK_ZBKC},
   1104   {"zbkx",   &gcc_options::x_riscv_zk_subext, MASK_ZBKX},
   1105   {"zknd",   &gcc_options::x_riscv_zk_subext, MASK_ZKND},
   1106   {"zkne",   &gcc_options::x_riscv_zk_subext, MASK_ZKNE},
   1107   {"zknh",   &gcc_options::x_riscv_zk_subext, MASK_ZKNH},
   1108   {"zkr",    &gcc_options::x_riscv_zk_subext, MASK_ZKR},
   1109   {"zksed",  &gcc_options::x_riscv_zk_subext, MASK_ZKSED},
   1110   {"zksh",   &gcc_options::x_riscv_zk_subext, MASK_ZKSH},
   1111   {"zkt",    &gcc_options::x_riscv_zk_subext, MASK_ZKT},
   1112 
   1113   {"zve32x",   &gcc_options::x_target_flags, MASK_VECTOR},
   1114   {"zve32f",   &gcc_options::x_target_flags, MASK_VECTOR},
   1115   {"zve64x",   &gcc_options::x_target_flags, MASK_VECTOR},
   1116   {"zve64f",   &gcc_options::x_target_flags, MASK_VECTOR},
   1117   {"zve64d",   &gcc_options::x_target_flags, MASK_VECTOR},
   1118 
   1119   /* We don't need to put complete ELEN/ELEN_FP info here, due to the
   1120      implication relation of vector extension.
   1121      e.g. v -> zve64d ... zve32x, so v has set MASK_VECTOR_ELEN_FP_64,
   1122      MASK_VECTOR_ELEN_FP_32, MASK_VECTOR_ELEN_64 and MASK_VECTOR_ELEN_32
   1123      due to the extension implication.  */
   1124   {"zve32x",   &gcc_options::x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_32},
   1125   {"zve32f",   &gcc_options::x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_FP_32},
   1126   {"zve64x",   &gcc_options::x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_64},
   1127   {"zve64f",   &gcc_options::x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_FP_32},
   1128   {"zve64d",   &gcc_options::x_riscv_vector_elen_flags, MASK_VECTOR_ELEN_FP_64},
   1129 
   1130   {"zvl32b",    &gcc_options::x_riscv_zvl_flags, MASK_ZVL32B},
   1131   {"zvl64b",    &gcc_options::x_riscv_zvl_flags, MASK_ZVL64B},
   1132   {"zvl128b",   &gcc_options::x_riscv_zvl_flags, MASK_ZVL128B},
   1133   {"zvl256b",   &gcc_options::x_riscv_zvl_flags, MASK_ZVL256B},
   1134   {"zvl512b",   &gcc_options::x_riscv_zvl_flags, MASK_ZVL512B},
   1135   {"zvl1024b",  &gcc_options::x_riscv_zvl_flags, MASK_ZVL1024B},
   1136   {"zvl2048b",  &gcc_options::x_riscv_zvl_flags, MASK_ZVL2048B},
   1137   {"zvl4096b",  &gcc_options::x_riscv_zvl_flags, MASK_ZVL4096B},
   1138   {"zvl8192b",  &gcc_options::x_riscv_zvl_flags, MASK_ZVL8192B},
   1139   {"zvl16384b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL16384B},
   1140   {"zvl32768b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL32768B},
   1141   {"zvl65536b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL65536B},
   1142 
   1143 
   1144   {NULL, NULL, 0}
   1145 };
   1146 
   1147 /* Parse a RISC-V ISA string into an option mask.  Must clear or set all arch
   1148    dependent mask bits, in case more than one -march string is passed.  */
   1149 
   1150 static void
   1151 riscv_parse_arch_string (const char *isa,
   1152 			 struct gcc_options *opts,
   1153 			 location_t loc)
   1154 {
   1155   riscv_subset_list *subset_list;
   1156   subset_list = riscv_subset_list::parse (isa, loc);
   1157   if (!subset_list)
   1158     return;
   1159 
   1160   if (opts)
   1161     {
   1162       const riscv_ext_flag_table_t *arch_ext_flag_tab;
   1163       /* Clean up target flags before we set.  */
   1164       for (arch_ext_flag_tab = &riscv_ext_flag_table[0];
   1165 	   arch_ext_flag_tab->ext;
   1166 	   ++arch_ext_flag_tab)
   1167 	opts->*arch_ext_flag_tab->var_ref &= ~arch_ext_flag_tab->mask;
   1168 
   1169       if (subset_list->xlen () == 32)
   1170 	opts->x_target_flags &= ~MASK_64BIT;
   1171       else if (subset_list->xlen () == 64)
   1172 	opts->x_target_flags |= MASK_64BIT;
   1173 
   1174 
   1175       for (arch_ext_flag_tab = &riscv_ext_flag_table[0];
   1176 	   arch_ext_flag_tab->ext;
   1177 	   ++arch_ext_flag_tab)
   1178 	{
   1179 	  if (subset_list->lookup (arch_ext_flag_tab->ext))
   1180 	    opts->*arch_ext_flag_tab->var_ref |= arch_ext_flag_tab->mask;
   1181 	}
   1182     }
   1183 
   1184   if (current_subset_list)
   1185     delete current_subset_list;
   1186 
   1187   current_subset_list = subset_list;
   1188 }
   1189 
   1190 /* Return the riscv_cpu_info entry for CPU, NULL if not found.  */
   1191 
   1192 const riscv_cpu_info *
   1193 riscv_find_cpu (const char *cpu)
   1194 {
   1195   const riscv_cpu_info *cpu_info = &riscv_cpu_tables[0];
   1196   for (;cpu_info->name != NULL; ++cpu_info)
   1197     {
   1198       const char *name = cpu_info->name;
   1199       if (strcmp (cpu, name) == 0)
   1200 	return cpu_info;
   1201     }
   1202   return NULL;
   1203 }
   1204 
   1205 /* Implement TARGET_HANDLE_OPTION.  */
   1206 
   1207 static bool
   1208 riscv_handle_option (struct gcc_options *opts,
   1209 		     struct gcc_options *opts_set ATTRIBUTE_UNUSED,
   1210 		     const struct cl_decoded_option *decoded,
   1211 		     location_t loc)
   1212 {
   1213   switch (decoded->opt_index)
   1214     {
   1215     case OPT_march_:
   1216       riscv_parse_arch_string (decoded->arg, opts, loc);
   1217       return true;
   1218 
   1219     case OPT_mcpu_:
   1220       if (riscv_find_cpu (decoded->arg) == NULL)
   1221 	error_at (loc, "%<-mcpu=%s%>: unknown CPU",
   1222 		  decoded->arg);
   1223       return true;
   1224 
   1225     default:
   1226       return true;
   1227     }
   1228 }
   1229 
   1230 /* Expand arch string with implied extensions.  */
   1231 
   1232 const char *
   1233 riscv_expand_arch (int argc ATTRIBUTE_UNUSED,
   1234 		   const char **argv)
   1235 {
   1236   gcc_assert (argc == 1);
   1237   location_t loc = UNKNOWN_LOCATION;
   1238   riscv_parse_arch_string (argv[0], NULL, loc);
   1239   const std::string arch = riscv_arch_str (false);
   1240   if (arch.length())
   1241     return xasprintf ("-march=%s", arch.c_str());
   1242   else
   1243     return "";
   1244 }
   1245 
   1246 /* Expand default -mtune option from -mcpu option, use default --with-tune value
   1247    if -mcpu don't have valid value.  */
   1248 
   1249 const char *
   1250 riscv_default_mtune (int argc, const char **argv)
   1251 {
   1252   gcc_assert (argc == 2);
   1253   const riscv_cpu_info *cpu = riscv_find_cpu (argv[0]);
   1254   const char *default_mtune = argv[1];
   1255   if (cpu)
   1256     return cpu->tune;
   1257   else
   1258     return default_mtune;
   1259 }
   1260 
   1261 /* Expand arch string with implied extensions from -mcpu option.  */
   1262 
   1263 const char *
   1264 riscv_expand_arch_from_cpu (int argc ATTRIBUTE_UNUSED,
   1265 			    const char **argv)
   1266 {
   1267   gcc_assert (argc > 0 && argc <= 2);
   1268   const char *default_arch_str = NULL;
   1269   const char *arch_str = NULL;
   1270   if (argc >= 2)
   1271     default_arch_str = argv[1];
   1272 
   1273   const riscv_cpu_info *cpu = riscv_find_cpu (argv[0]);
   1274 
   1275   if (cpu == NULL)
   1276     {
   1277       if (default_arch_str == NULL)
   1278 	return "";
   1279       else
   1280 	arch_str = default_arch_str;
   1281     }
   1282   else
   1283     arch_str = cpu->arch;
   1284 
   1285   location_t loc = UNKNOWN_LOCATION;
   1286 
   1287   riscv_parse_arch_string (arch_str, NULL, loc);
   1288   const std::string arch = riscv_arch_str (false);
   1289   return xasprintf ("-march=%s", arch.c_str());
   1290 }
   1291 
   1292 
   1293 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
   1294 static const struct default_options riscv_option_optimization_table[] =
   1295   {
   1296     { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
   1297     { OPT_LEVELS_2_PLUS, OPT_free, NULL, 1 },
   1298     { OPT_LEVELS_NONE, 0, NULL, 0 }
   1299   };
   1300 
   1301 #undef TARGET_OPTION_OPTIMIZATION_TABLE
   1302 #define TARGET_OPTION_OPTIMIZATION_TABLE riscv_option_optimization_table
   1303 
   1304 #undef TARGET_HANDLE_OPTION
   1305 #define TARGET_HANDLE_OPTION riscv_handle_option
   1306 
   1307 struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
   1308