Home | History | Annotate | Line # | Download | only in loongarch
      1  1.1  mrg /* Subroutines for loongarch-specific option handling.
      2  1.1  mrg    Copyright (C) 2021-2022 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by Loongson Ltd.
      4  1.1  mrg 
      5  1.1  mrg This file is part of GCC.
      6  1.1  mrg 
      7  1.1  mrg GCC is free software; you can redistribute it and/or modify
      8  1.1  mrg it under the terms of the GNU General Public License as published by
      9  1.1  mrg the Free Software Foundation; either version 3, or (at your option)
     10  1.1  mrg any later version.
     11  1.1  mrg 
     12  1.1  mrg GCC is distributed in the hope that it will be useful,
     13  1.1  mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  mrg GNU General Public License for more details.
     16  1.1  mrg 
     17  1.1  mrg You should have received a copy of the GNU General Public License
     18  1.1  mrg along with GCC; see the file COPYING3.  If not see
     19  1.1  mrg <http://www.gnu.org/licenses/>.  */
     20  1.1  mrg 
     21  1.1  mrg #define IN_TARGET_CODE 1
     22  1.1  mrg 
     23  1.1  mrg #include "config.h"
     24  1.1  mrg #include "system.h"
     25  1.1  mrg #include "coretypes.h"
     26  1.1  mrg #include "tm.h"
     27  1.1  mrg #include "obstack.h"
     28  1.1  mrg #include "diagnostic-core.h"
     29  1.1  mrg #include "loongarch-cpu.h"
     30  1.1  mrg #include "loongarch-opts.h"
     31  1.1  mrg #include "loongarch-str.h"
     32  1.1  mrg 
     33  1.1  mrg struct loongarch_target la_target;
     34  1.1  mrg 
     35  1.1  mrg /* ABI-related configuration.  */
     36  1.1  mrg #define ABI_COUNT (sizeof(abi_priority_list)/sizeof(struct loongarch_abi))
     37  1.1  mrg static const struct loongarch_abi
     38  1.1  mrg abi_priority_list[] = {
     39  1.1  mrg     {ABI_BASE_LP64D, ABI_EXT_BASE},
     40  1.1  mrg     {ABI_BASE_LP64F, ABI_EXT_BASE},
     41  1.1  mrg     {ABI_BASE_LP64S, ABI_EXT_BASE},
     42  1.1  mrg };
     43  1.1  mrg 
     44  1.1  mrg /* Initialize enabled_abi_types from TM_MULTILIB_LIST.  */
     45  1.1  mrg #ifdef LA_DISABLE_MULTILIB
     46  1.1  mrg #define MULTILIB_LIST_LEN 1
     47  1.1  mrg #else
     48  1.1  mrg #define MULTILIB_LIST_LEN (sizeof (tm_multilib_list) / sizeof (int) / 2)
     49  1.1  mrg static const int tm_multilib_list[] = { TM_MULTILIB_LIST };
     50  1.1  mrg #endif
     51  1.1  mrg static int enabled_abi_types[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES] = { 0 };
     52  1.1  mrg 
     53  1.1  mrg #define isa_required(ABI) (abi_minimal_isa[(ABI).base][(ABI).ext])
     54  1.1  mrg extern "C" const struct loongarch_isa
     55  1.1  mrg abi_minimal_isa[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES];
     56  1.1  mrg 
     57  1.1  mrg static inline int
     58  1.1  mrg is_multilib_enabled (struct loongarch_abi abi)
     59  1.1  mrg {
     60  1.1  mrg   return enabled_abi_types[abi.base][abi.ext];
     61  1.1  mrg }
     62  1.1  mrg 
     63  1.1  mrg static void
     64  1.1  mrg init_enabled_abi_types ()
     65  1.1  mrg {
     66  1.1  mrg #ifdef LA_DISABLE_MULTILIB
     67  1.1  mrg   enabled_abi_types[DEFAULT_ABI_BASE][DEFAULT_ABI_EXT] = 1;
     68  1.1  mrg #else
     69  1.1  mrg   int abi_base, abi_ext;
     70  1.1  mrg   for (unsigned int i = 0; i < MULTILIB_LIST_LEN; i++)
     71  1.1  mrg     {
     72  1.1  mrg       abi_base = tm_multilib_list[i << 1];
     73  1.1  mrg       abi_ext = tm_multilib_list[(i << 1) + 1];
     74  1.1  mrg       enabled_abi_types[abi_base][abi_ext] = 1;
     75  1.1  mrg     }
     76  1.1  mrg #endif
     77  1.1  mrg }
     78  1.1  mrg 
     79  1.1  mrg /* Switch masks.  */
     80  1.1  mrg #undef M
     81  1.1  mrg #define M(NAME) OPTION_MASK_##NAME
     82  1.1  mrg const int loongarch_switch_mask[N_SWITCH_TYPES] = {
     83  1.1  mrg   /* SW_SOFT_FLOAT */    M(FORCE_SOFTF),
     84  1.1  mrg   /* SW_SINGLE_FLOAT */  M(FORCE_F32),
     85  1.1  mrg   /* SW_DOUBLE_FLOAT */  M(FORCE_F64),
     86  1.1  mrg };
     87  1.1  mrg #undef M
     88  1.1  mrg 
     89  1.1  mrg /* String processing.  */
     90  1.1  mrg static struct obstack msg_obstack;
     91  1.1  mrg #define APPEND_STRING(STR) obstack_grow (&msg_obstack, STR, strlen(STR));
     92  1.1  mrg #define APPEND1(CH) obstack_1grow(&msg_obstack, CH);
     93  1.1  mrg 
     94  1.1  mrg static const char* abi_str (struct loongarch_abi abi);
     95  1.1  mrg static const char* isa_str (const struct loongarch_isa *isa, char separator);
     96  1.1  mrg static const char* arch_str (const struct loongarch_target *target);
     97  1.1  mrg static const char* multilib_enabled_abi_list ();
     98  1.1  mrg 
     99  1.1  mrg /* Misc */
    100  1.1  mrg static struct loongarch_abi isa_default_abi (const struct loongarch_isa *isa);
    101  1.1  mrg static int isa_base_compat_p (const struct loongarch_isa *set1,
    102  1.1  mrg 			      const struct loongarch_isa *set2);
    103  1.1  mrg static int isa_fpu_compat_p (const struct loongarch_isa *set1,
    104  1.1  mrg 			     const struct loongarch_isa *set2);
    105  1.1  mrg static int abi_compat_p (const struct loongarch_isa *isa,
    106  1.1  mrg 			 struct loongarch_abi abi);
    107  1.1  mrg static int abi_default_cpu_arch (struct loongarch_abi abi);
    108  1.1  mrg 
    109  1.1  mrg /* Checking configure-time defaults.  */
    110  1.1  mrg #ifndef DEFAULT_ABI_BASE
    111  1.1  mrg #error missing definition of DEFAULT_ABI_BASE in ${tm_defines}.
    112  1.1  mrg #endif
    113  1.1  mrg 
    114  1.1  mrg #ifndef DEFAULT_ABI_EXT
    115  1.1  mrg #error missing definition of DEFAULT_ABI_EXT in ${tm_defines}.
    116  1.1  mrg #endif
    117  1.1  mrg 
    118  1.1  mrg #ifndef DEFAULT_CPU_ARCH
    119  1.1  mrg #error missing definition of DEFAULT_CPU_ARCH in ${tm_defines}.
    120  1.1  mrg #endif
    121  1.1  mrg 
    122  1.1  mrg #ifndef DEFAULT_ISA_EXT_FPU
    123  1.1  mrg #error missing definition of DEFAULT_ISA_EXT_FPU in ${tm_defines}.
    124  1.1  mrg #endif
    125  1.1  mrg 
    126  1.1  mrg /* Handle combinations of -m machine option values
    127  1.1  mrg    (see loongarch.opt and loongarch-opts.h).  */
    128  1.1  mrg void
    129  1.1  mrg loongarch_config_target (struct loongarch_target *target,
    130  1.1  mrg 			 HOST_WIDE_INT opt_switches,
    131  1.1  mrg 			 int opt_arch, int opt_tune, int opt_fpu,
    132  1.1  mrg 			 int opt_abi_base, int opt_abi_ext,
    133  1.1  mrg 			 int opt_cmodel, int follow_multilib_list)
    134  1.1  mrg {
    135  1.1  mrg   struct loongarch_target t;
    136  1.1  mrg 
    137  1.1  mrg   if (!target)
    138  1.1  mrg     return;
    139  1.1  mrg 
    140  1.1  mrg   /* Initialization */
    141  1.1  mrg   init_enabled_abi_types ();
    142  1.1  mrg   obstack_init (&msg_obstack);
    143  1.1  mrg 
    144  1.1  mrg   struct {
    145  1.1  mrg     int arch, tune, fpu, abi_base, abi_ext, cmodel;
    146  1.1  mrg   } constrained = {
    147  1.1  mrg       M_OPT_ABSENT(opt_arch)     ? 0 : 1,
    148  1.1  mrg       M_OPT_ABSENT(opt_tune)     ? 0 : 1,
    149  1.1  mrg       M_OPT_ABSENT(opt_fpu)      ? 0 : 1,
    150  1.1  mrg       M_OPT_ABSENT(opt_abi_base) ? 0 : 1,
    151  1.1  mrg       M_OPT_ABSENT(opt_abi_ext)  ? 0 : 1,
    152  1.1  mrg       M_OPT_ABSENT(opt_cmodel)   ? 0 : 1,
    153  1.1  mrg   };
    154  1.1  mrg 
    155  1.1  mrg #define on(NAME) ((loongarch_switch_mask[(SW_##NAME)] & opt_switches) \
    156  1.1  mrg 		  && (on_switch = (SW_##NAME), 1))
    157  1.1  mrg   int on_switch;
    158  1.1  mrg 
    159  1.1  mrg   /* 1.  Target ABI */
    160  1.1  mrg   t.abi.base = constrained.abi_base ? opt_abi_base : DEFAULT_ABI_BASE;
    161  1.1  mrg 
    162  1.1  mrg   t.abi.ext = constrained.abi_ext ? opt_abi_ext : DEFAULT_ABI_EXT;
    163  1.1  mrg 
    164  1.1  mrg   /* Extra switch handling.  */
    165  1.1  mrg   if (on (SOFT_FLOAT) || on (SINGLE_FLOAT) || on (DOUBLE_FLOAT))
    166  1.1  mrg     {
    167  1.1  mrg       switch (on_switch)
    168  1.1  mrg 	{
    169  1.1  mrg 	  case SW_SOFT_FLOAT:
    170  1.1  mrg 	    opt_fpu = ISA_EXT_NOFPU;
    171  1.1  mrg 	    break;
    172  1.1  mrg 
    173  1.1  mrg 	  case SW_SINGLE_FLOAT:
    174  1.1  mrg 	    opt_fpu = ISA_EXT_FPU32;
    175  1.1  mrg 	    break;
    176  1.1  mrg 
    177  1.1  mrg 	  case SW_DOUBLE_FLOAT:
    178  1.1  mrg 	    opt_fpu = ISA_EXT_FPU64;
    179  1.1  mrg 	    break;
    180  1.1  mrg 
    181  1.1  mrg 	  default:
    182  1.1  mrg 	    gcc_unreachable();
    183  1.1  mrg 	}
    184  1.1  mrg       constrained.fpu = 1;
    185  1.1  mrg 
    186  1.1  mrg       /* The target ISA is not ready yet, but (isa_required (t.abi)
    187  1.1  mrg 	 + forced fpu) is enough for computing the forced base ABI.  */
    188  1.1  mrg       struct loongarch_isa default_isa = isa_required (t.abi);
    189  1.1  mrg       struct loongarch_isa force_isa = default_isa;
    190  1.1  mrg       struct loongarch_abi force_abi = t.abi;
    191  1.1  mrg       force_isa.fpu = opt_fpu;
    192  1.1  mrg       force_abi.base = isa_default_abi (&force_isa).base;
    193  1.1  mrg 
    194  1.1  mrg       if (constrained.abi_base && (t.abi.base != force_abi.base))
    195  1.1  mrg 	inform (UNKNOWN_LOCATION,
    196  1.1  mrg 		"%<-m%s%> overrides %<-m%s=%s%>, adjusting ABI to %qs",
    197  1.1  mrg 		loongarch_switch_strings[on_switch],
    198  1.1  mrg 		OPTSTR_ABI_BASE, loongarch_abi_base_strings[t.abi.base],
    199  1.1  mrg 		abi_str (force_abi));
    200  1.1  mrg 
    201  1.1  mrg       t.abi.base = force_abi.base;
    202  1.1  mrg     }
    203  1.1  mrg 
    204  1.1  mrg #ifdef LA_DISABLE_MULTILIB
    205  1.1  mrg   if (follow_multilib_list)
    206  1.1  mrg     if (t.abi.base != DEFAULT_ABI_BASE || t.abi.ext != DEFAULT_ABI_EXT)
    207  1.1  mrg       {
    208  1.1  mrg 	static const struct loongarch_abi default_abi
    209  1.1  mrg 	  = {DEFAULT_ABI_BASE, DEFAULT_ABI_EXT};
    210  1.1  mrg 
    211  1.1  mrg 	warning (0, "ABI changed (%qs to %qs) while multilib is disabled",
    212  1.1  mrg 		 abi_str (default_abi), abi_str (t.abi));
    213  1.1  mrg       }
    214  1.1  mrg #endif
    215  1.1  mrg 
    216  1.1  mrg   /* 2.  Target CPU */
    217  1.1  mrg   t.cpu_arch = constrained.arch ? opt_arch : DEFAULT_CPU_ARCH;
    218  1.1  mrg 
    219  1.1  mrg   t.cpu_tune = constrained.tune ? opt_tune
    220  1.1  mrg     : (constrained.arch ? DEFAULT_CPU_ARCH : DEFAULT_CPU_TUNE);
    221  1.1  mrg 
    222  1.1  mrg #ifdef __loongarch__
    223  1.1  mrg   /* For native compilers, gather local CPU information
    224  1.1  mrg      and fill the "CPU_NATIVE" index of arrays defined in
    225  1.1  mrg      loongarch-cpu.c.  */
    226  1.1  mrg 
    227  1.1  mrg   t.cpu_native = fill_native_cpu_config (t.cpu_arch == CPU_NATIVE,
    228  1.1  mrg 					 t.cpu_tune == CPU_NATIVE);
    229  1.1  mrg 
    230  1.1  mrg #else
    231  1.1  mrg   if (t.cpu_arch == CPU_NATIVE)
    232  1.1  mrg     fatal_error (UNKNOWN_LOCATION,
    233  1.1  mrg 		 "%qs does not work on a cross compiler",
    234  1.1  mrg 		 "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE);
    235  1.1  mrg 
    236  1.1  mrg   else if (t.cpu_tune == CPU_NATIVE)
    237  1.1  mrg     fatal_error (UNKNOWN_LOCATION,
    238  1.1  mrg 		 "%qs does not work on a cross compiler",
    239  1.1  mrg 		 "-m" OPTSTR_TUNE "=" STR_CPU_NATIVE);
    240  1.1  mrg #endif
    241  1.1  mrg 
    242  1.1  mrg   /* 3.  Target ISA */
    243  1.1  mrg config_target_isa:
    244  1.1  mrg 
    245  1.1  mrg   /* Get default ISA from "-march" or its default value.  */
    246  1.1  mrg   t.isa = loongarch_cpu_default_isa[LARCH_ACTUAL_ARCH];
    247  1.1  mrg 
    248  1.1  mrg   /* Apply incremental changes.  */
    249  1.1  mrg   /* "-march=native" overrides the default FPU type.  */
    250  1.1  mrg   t.isa.fpu = constrained.fpu ? opt_fpu :
    251  1.1  mrg     ((t.cpu_arch == CPU_NATIVE && constrained.arch) ?
    252  1.1  mrg      t.isa.fpu : DEFAULT_ISA_EXT_FPU);
    253  1.1  mrg 
    254  1.1  mrg 
    255  1.1  mrg   /* 4.  ABI-ISA compatibility */
    256  1.1  mrg   /* Note:
    257  1.1  mrg      - There IS a unique default -march value for each ABI type
    258  1.1  mrg        (config.gcc: triplet -> abi -> default arch).
    259  1.1  mrg 
    260  1.1  mrg      - If the base ABI is incompatible with the default arch,
    261  1.1  mrg        try using the default -march it implies (and mark it
    262  1.1  mrg        as "constrained" this time), then re-apply step 3.  */
    263  1.1  mrg 
    264  1.1  mrg   struct loongarch_abi abi_tmp;
    265  1.1  mrg   const struct loongarch_isa* isa_min;
    266  1.1  mrg 
    267  1.1  mrg   abi_tmp = t.abi;
    268  1.1  mrg   isa_min = &isa_required (abi_tmp);
    269  1.1  mrg 
    270  1.1  mrg   if (isa_base_compat_p (&t.isa, isa_min)); /* OK.  */
    271  1.1  mrg   else if (!constrained.arch)
    272  1.1  mrg     {
    273  1.1  mrg       /* Base architecture can only be implied by -march,
    274  1.1  mrg 	 so we adjust that first if it is not constrained.  */
    275  1.1  mrg       int fallback_arch = abi_default_cpu_arch (t.abi);
    276  1.1  mrg 
    277  1.1  mrg       if (t.cpu_arch == CPU_NATIVE)
    278  1.1  mrg 	warning (0, "your native CPU architecture (%qs) "
    279  1.1  mrg 		 "does not support %qs ABI, falling back to %<-m%s=%s%>",
    280  1.1  mrg 		 arch_str (&t), abi_str (t.abi), OPTSTR_ARCH,
    281  1.1  mrg 		 loongarch_cpu_strings[fallback_arch]);
    282  1.1  mrg       else
    283  1.1  mrg 	warning (0, "default CPU architecture (%qs) "
    284  1.1  mrg 		 "does not support %qs ABI, falling back to %<-m%s=%s%>",
    285  1.1  mrg 		 arch_str (&t), abi_str (t.abi), OPTSTR_ARCH,
    286  1.1  mrg 		 loongarch_cpu_strings[fallback_arch]);
    287  1.1  mrg 
    288  1.1  mrg       t.cpu_arch = fallback_arch;
    289  1.1  mrg       constrained.arch = 1;
    290  1.1  mrg       goto config_target_isa;
    291  1.1  mrg     }
    292  1.1  mrg   else if (!constrained.abi_base)
    293  1.1  mrg     {
    294  1.1  mrg       /* If -march is given while -mabi is not,
    295  1.1  mrg 	 try selecting another base ABI type.  */
    296  1.1  mrg       abi_tmp.base = isa_default_abi (&t.isa).base;
    297  1.1  mrg     }
    298  1.1  mrg   else
    299  1.1  mrg     goto fatal;
    300  1.1  mrg 
    301  1.1  mrg   if (isa_fpu_compat_p (&t.isa, isa_min)); /* OK.  */
    302  1.1  mrg   else if (!constrained.fpu)
    303  1.1  mrg     t.isa.fpu = isa_min->fpu;
    304  1.1  mrg   else if (!constrained.abi_base)
    305  1.1  mrg     /* If -march is compatible with the default ABI
    306  1.1  mrg        while -mfpu is not.  */
    307  1.1  mrg     abi_tmp.base = isa_default_abi (&t.isa).base;
    308  1.1  mrg   else
    309  1.1  mrg     goto fatal;
    310  1.1  mrg 
    311  1.1  mrg   if (0)
    312  1.1  mrg fatal:
    313  1.1  mrg     fatal_error (UNKNOWN_LOCATION,
    314  1.1  mrg 		 "unable to implement ABI %qs with instruction set %qs",
    315  1.1  mrg 		 abi_str (t.abi), isa_str (&t.isa, '/'));
    316  1.1  mrg 
    317  1.1  mrg 
    318  1.1  mrg   /* Using the fallback ABI.  */
    319  1.1  mrg   if (abi_tmp.base != t.abi.base || abi_tmp.ext != t.abi.ext)
    320  1.1  mrg     {
    321  1.1  mrg       /* This flag is only set in the GCC driver.  */
    322  1.1  mrg       if (follow_multilib_list)
    323  1.1  mrg 	{
    324  1.1  mrg 
    325  1.1  mrg 	  /* Continue falling back until we find a feasible ABI type
    326  1.1  mrg 	     enabled by TM_MULTILIB_LIST.  */
    327  1.1  mrg 	  if (!is_multilib_enabled (abi_tmp))
    328  1.1  mrg 	    {
    329  1.1  mrg 	      for (unsigned int i = 0; i < ABI_COUNT; i++)
    330  1.1  mrg 		{
    331  1.1  mrg 		  if (is_multilib_enabled (abi_priority_list[i])
    332  1.1  mrg 		      && abi_compat_p (&t.isa, abi_priority_list[i]))
    333  1.1  mrg 		    {
    334  1.1  mrg 		      abi_tmp = abi_priority_list[i];
    335  1.1  mrg 
    336  1.1  mrg 		      warning (0, "ABI %qs cannot be implemented due to "
    337  1.1  mrg 			       "limited instruction set %qs, "
    338  1.1  mrg 			       "falling back to %qs", abi_str (t.abi),
    339  1.1  mrg 			       isa_str (&t.isa, '/'), abi_str (abi_tmp));
    340  1.1  mrg 
    341  1.1  mrg 		      goto fallback;
    342  1.1  mrg 		    }
    343  1.1  mrg 		}
    344  1.1  mrg 
    345  1.1  mrg 	      /* Otherwise, keep using abi_tmp with a warning.  */
    346  1.1  mrg #ifdef LA_DISABLE_MULTILIB
    347  1.1  mrg 	      warning (0, "instruction set %qs cannot implement "
    348  1.1  mrg 		       "default ABI %qs, falling back to %qs",
    349  1.1  mrg 		       isa_str (&t.isa, '/'), abi_str (t.abi),
    350  1.1  mrg 		       abi_str (abi_tmp));
    351  1.1  mrg #else
    352  1.1  mrg 	      warning (0, "no multilib-enabled ABI (%qs) can be implemented "
    353  1.1  mrg 		       "with instruction set %qs, falling back to %qs",
    354  1.1  mrg 		       multilib_enabled_abi_list (),
    355  1.1  mrg 		       isa_str (&t.isa, '/'), abi_str (abi_tmp));
    356  1.1  mrg #endif
    357  1.1  mrg 	    }
    358  1.1  mrg 	}
    359  1.1  mrg 
    360  1.1  mrg fallback:
    361  1.1  mrg       t.abi = abi_tmp;
    362  1.1  mrg     }
    363  1.1  mrg   else if (follow_multilib_list)
    364  1.1  mrg     {
    365  1.1  mrg       if (!is_multilib_enabled (t.abi))
    366  1.1  mrg 	{
    367  1.1  mrg 	  inform (UNKNOWN_LOCATION,
    368  1.1  mrg 		  "ABI %qs is not enabled at configure-time, "
    369  1.1  mrg 		  "the linker might report an error", abi_str (t.abi));
    370  1.1  mrg 
    371  1.1  mrg 	  inform (UNKNOWN_LOCATION, "ABI with startfiles: %s",
    372  1.1  mrg 		  multilib_enabled_abi_list ());
    373  1.1  mrg 	}
    374  1.1  mrg     }
    375  1.1  mrg 
    376  1.1  mrg 
    377  1.1  mrg   /* 5.  Target code model */
    378  1.1  mrg   t.cmodel = constrained.cmodel ? opt_cmodel : CMODEL_NORMAL;
    379  1.1  mrg 
    380  1.1  mrg   /* Cleanup and return.  */
    381  1.1  mrg   obstack_free (&msg_obstack, NULL);
    382  1.1  mrg   *target = t;
    383  1.1  mrg }
    384  1.1  mrg 
    385  1.1  mrg /* Returns the default ABI for the given instruction set.  */
    386  1.1  mrg static inline struct loongarch_abi
    387  1.1  mrg isa_default_abi (const struct loongarch_isa *isa)
    388  1.1  mrg {
    389  1.1  mrg   struct loongarch_abi abi;
    390  1.1  mrg 
    391  1.1  mrg   switch (isa->fpu)
    392  1.1  mrg     {
    393  1.1  mrg       case ISA_EXT_FPU64:
    394  1.1  mrg 	if (isa->base == ISA_BASE_LA64V100)
    395  1.1  mrg 	  abi.base = ABI_BASE_LP64D;
    396  1.1  mrg 	break;
    397  1.1  mrg 
    398  1.1  mrg       case ISA_EXT_FPU32:
    399  1.1  mrg 	if (isa->base == ISA_BASE_LA64V100)
    400  1.1  mrg 	  abi.base = ABI_BASE_LP64F;
    401  1.1  mrg 	break;
    402  1.1  mrg 
    403  1.1  mrg       case ISA_EXT_NOFPU:
    404  1.1  mrg 	if (isa->base == ISA_BASE_LA64V100)
    405  1.1  mrg 	  abi.base = ABI_BASE_LP64S;
    406  1.1  mrg 	break;
    407  1.1  mrg 
    408  1.1  mrg       default:
    409  1.1  mrg 	gcc_unreachable ();
    410  1.1  mrg     }
    411  1.1  mrg 
    412  1.1  mrg   abi.ext = ABI_EXT_BASE;
    413  1.1  mrg   return abi;
    414  1.1  mrg }
    415  1.1  mrg 
    416  1.1  mrg /* Check if set2 is a subset of set1.  */
    417  1.1  mrg static inline int
    418  1.1  mrg isa_base_compat_p (const struct loongarch_isa *set1,
    419  1.1  mrg 		   const struct loongarch_isa *set2)
    420  1.1  mrg {
    421  1.1  mrg   switch (set2->base)
    422  1.1  mrg     {
    423  1.1  mrg       case ISA_BASE_LA64V100:
    424  1.1  mrg 	return (set1->base == ISA_BASE_LA64V100);
    425  1.1  mrg 
    426  1.1  mrg       default:
    427  1.1  mrg 	gcc_unreachable ();
    428  1.1  mrg     }
    429  1.1  mrg }
    430  1.1  mrg 
    431  1.1  mrg static inline int
    432  1.1  mrg isa_fpu_compat_p (const struct loongarch_isa *set1,
    433  1.1  mrg 		  const struct loongarch_isa *set2)
    434  1.1  mrg {
    435  1.1  mrg   switch (set2->fpu)
    436  1.1  mrg     {
    437  1.1  mrg       case ISA_EXT_FPU64:
    438  1.1  mrg 	return set1->fpu == ISA_EXT_FPU64;
    439  1.1  mrg 
    440  1.1  mrg       case ISA_EXT_FPU32:
    441  1.1  mrg 	return set1->fpu == ISA_EXT_FPU32 || set1->fpu == ISA_EXT_FPU64;
    442  1.1  mrg 
    443  1.1  mrg       case ISA_EXT_NOFPU:
    444  1.1  mrg 	return 1;
    445  1.1  mrg 
    446  1.1  mrg       default:
    447  1.1  mrg 	gcc_unreachable ();
    448  1.1  mrg     }
    449  1.1  mrg 
    450  1.1  mrg }
    451  1.1  mrg 
    452  1.1  mrg static inline int
    453  1.1  mrg abi_compat_p (const struct loongarch_isa *isa, struct loongarch_abi abi)
    454  1.1  mrg {
    455  1.1  mrg   int compatible = 1;
    456  1.1  mrg   const struct loongarch_isa *isa2 = &isa_required (abi);
    457  1.1  mrg 
    458  1.1  mrg   /* Append conditionals for new ISA components below.  */
    459  1.1  mrg   compatible = compatible && isa_base_compat_p (isa, isa2);
    460  1.1  mrg   compatible = compatible && isa_fpu_compat_p (isa, isa2);
    461  1.1  mrg   return compatible;
    462  1.1  mrg }
    463  1.1  mrg 
    464  1.1  mrg /* The behavior of this function should be consistent
    465  1.1  mrg    with config.gcc.  */
    466  1.1  mrg static inline int
    467  1.1  mrg abi_default_cpu_arch (struct loongarch_abi abi)
    468  1.1  mrg {
    469  1.1  mrg   switch (abi.base)
    470  1.1  mrg     {
    471  1.1  mrg       case ABI_BASE_LP64D:
    472  1.1  mrg       case ABI_BASE_LP64F:
    473  1.1  mrg       case ABI_BASE_LP64S:
    474  1.1  mrg 	if (abi.ext == ABI_EXT_BASE)
    475  1.1  mrg 	  return CPU_LOONGARCH64;
    476  1.1  mrg     }
    477  1.1  mrg   gcc_unreachable ();
    478  1.1  mrg }
    479  1.1  mrg 
    480  1.1  mrg static const char*
    481  1.1  mrg abi_str (struct loongarch_abi abi)
    482  1.1  mrg {
    483  1.1  mrg   /* "/base" can be omitted.  */
    484  1.1  mrg   if (abi.ext == ABI_EXT_BASE)
    485  1.1  mrg     return (const char*)
    486  1.1  mrg       obstack_copy0 (&msg_obstack, loongarch_abi_base_strings[abi.base],
    487  1.1  mrg 		     strlen (loongarch_abi_base_strings[abi.base]));
    488  1.1  mrg   else
    489  1.1  mrg     {
    490  1.1  mrg       APPEND_STRING (loongarch_abi_base_strings[abi.base])
    491  1.1  mrg       APPEND1 ('/')
    492  1.1  mrg       APPEND_STRING (loongarch_abi_ext_strings[abi.ext])
    493  1.1  mrg       APPEND1 ('\0')
    494  1.1  mrg 
    495  1.1  mrg       return XOBFINISH (&msg_obstack, const char *);
    496  1.1  mrg     }
    497  1.1  mrg }
    498  1.1  mrg 
    499  1.1  mrg static const char*
    500  1.1  mrg isa_str (const struct loongarch_isa *isa, char separator)
    501  1.1  mrg {
    502  1.1  mrg   APPEND_STRING (loongarch_isa_base_strings[isa->base])
    503  1.1  mrg   APPEND1 (separator)
    504  1.1  mrg 
    505  1.1  mrg   if (isa->fpu == ISA_EXT_NOFPU)
    506  1.1  mrg     {
    507  1.1  mrg       APPEND_STRING ("no" OPTSTR_ISA_EXT_FPU)
    508  1.1  mrg     }
    509  1.1  mrg   else
    510  1.1  mrg     {
    511  1.1  mrg       APPEND_STRING (OPTSTR_ISA_EXT_FPU)
    512  1.1  mrg       APPEND_STRING (loongarch_isa_ext_strings[isa->fpu])
    513  1.1  mrg     }
    514  1.1  mrg   APPEND1 ('\0')
    515  1.1  mrg 
    516  1.1  mrg   /* Add more here.  */
    517  1.1  mrg 
    518  1.1  mrg   return XOBFINISH (&msg_obstack, const char *);
    519  1.1  mrg }
    520  1.1  mrg 
    521  1.1  mrg static const char*
    522  1.1  mrg arch_str (const struct loongarch_target *target)
    523  1.1  mrg {
    524  1.1  mrg   if (target->cpu_arch == CPU_NATIVE)
    525  1.1  mrg     {
    526  1.1  mrg       if (target->cpu_native == CPU_NATIVE)
    527  1.1  mrg 	{
    528  1.1  mrg 	  /* Describe a native CPU with unknown PRID.  */
    529  1.1  mrg 	  const char* isa_string = isa_str (&target->isa, ',');
    530  1.1  mrg 	  APPEND_STRING ("PRID: 0x")
    531  1.1  mrg 	  APPEND_STRING (get_native_prid_str ())
    532  1.1  mrg 	  APPEND_STRING (", ISA features: ")
    533  1.1  mrg 	  APPEND_STRING (isa_string)
    534  1.1  mrg 	  APPEND1 ('\0')
    535  1.1  mrg 	}
    536  1.1  mrg       else
    537  1.1  mrg 	APPEND_STRING (loongarch_cpu_strings[target->cpu_native]);
    538  1.1  mrg     }
    539  1.1  mrg   else
    540  1.1  mrg     APPEND_STRING (loongarch_cpu_strings[target->cpu_arch]);
    541  1.1  mrg 
    542  1.1  mrg   APPEND1 ('\0')
    543  1.1  mrg   return XOBFINISH (&msg_obstack, const char *);
    544  1.1  mrg }
    545  1.1  mrg 
    546  1.1  mrg static const char*
    547  1.1  mrg multilib_enabled_abi_list ()
    548  1.1  mrg {
    549  1.1  mrg   int enabled_abi_idx[MULTILIB_LIST_LEN] = { 0 };
    550  1.1  mrg   const char* enabled_abi_str[MULTILIB_LIST_LEN] = { NULL };
    551  1.1  mrg   unsigned int j = 0;
    552  1.1  mrg 
    553  1.1  mrg   for (unsigned int i = 0; i < ABI_COUNT && j < MULTILIB_LIST_LEN; i++)
    554  1.1  mrg     {
    555  1.1  mrg       if (enabled_abi_types[abi_priority_list[i].base]
    556  1.1  mrg 	  [abi_priority_list[i].ext])
    557  1.1  mrg 	{
    558  1.1  mrg 	  enabled_abi_idx[j++] = i;
    559  1.1  mrg 	}
    560  1.1  mrg     }
    561  1.1  mrg 
    562  1.1  mrg   for (unsigned int k = 0; k < j; k++)
    563  1.1  mrg     {
    564  1.1  mrg       enabled_abi_str[k] = abi_str (abi_priority_list[enabled_abi_idx[k]]);
    565  1.1  mrg     }
    566  1.1  mrg 
    567  1.1  mrg   for (unsigned int k = 0; k < j - 1; k++)
    568  1.1  mrg     {
    569  1.1  mrg       APPEND_STRING (enabled_abi_str[k])
    570  1.1  mrg       APPEND1 (',')
    571  1.1  mrg       APPEND1 (' ')
    572  1.1  mrg     }
    573  1.1  mrg   APPEND_STRING (enabled_abi_str[j - 1])
    574  1.1  mrg   APPEND1 ('\0')
    575  1.1  mrg 
    576  1.1  mrg   return XOBFINISH (&msg_obstack, const char *);
    577  1.1  mrg }
    578  1.1  mrg 
    579  1.1  mrg /* option status feedback for "gcc --help=target -Q" */
    580  1.1  mrg void
    581  1.1  mrg loongarch_update_gcc_opt_status (struct loongarch_target *target,
    582  1.1  mrg 				 struct gcc_options *opts,
    583  1.1  mrg 				 struct gcc_options *opts_set)
    584  1.1  mrg {
    585  1.1  mrg   (void) opts_set;
    586  1.1  mrg 
    587  1.1  mrg   /* status of -mabi */
    588  1.1  mrg   opts->x_la_opt_abi_base = target->abi.base;
    589  1.1  mrg 
    590  1.1  mrg   /* status of -march and -mtune */
    591  1.1  mrg   opts->x_la_opt_cpu_arch = target->cpu_arch;
    592  1.1  mrg   opts->x_la_opt_cpu_tune = target->cpu_tune;
    593  1.1  mrg 
    594  1.1  mrg   /* status of -mcmodel */
    595  1.1  mrg   opts->x_la_opt_cmodel = target->cmodel;
    596  1.1  mrg 
    597  1.1  mrg   /* status of -mfpu */
    598  1.1  mrg   opts->x_la_opt_fpu = target->isa.fpu;
    599  1.1  mrg }
    600