]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/loongarch/loongarch-opts.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / config / loongarch / loongarch-opts.cc
CommitLineData
b44786f6 1/* Subroutines for loongarch-specific option handling.
a945c346 2 Copyright (C) 2021-2024 Free Software Foundation, Inc.
b44786f6 3 Contributed by Loongson Ltd.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#define IN_TARGET_CODE 1
22
23#include "config.h"
24#include "system.h"
25#include "coretypes.h"
26#include "tm.h"
27#include "obstack.h"
28#include "diagnostic-core.h"
bb4a8198 29
b44786f6 30#include "loongarch-cpu.h"
31#include "loongarch-opts.h"
32#include "loongarch-str.h"
bb4a8198 33#include "loongarch-def.h"
b44786f6 34
35struct loongarch_target la_target;
36
37/* ABI-related configuration. */
38#define ABI_COUNT (sizeof(abi_priority_list)/sizeof(struct loongarch_abi))
39static const struct loongarch_abi
40abi_priority_list[] = {
41 {ABI_BASE_LP64D, ABI_EXT_BASE},
42 {ABI_BASE_LP64F, ABI_EXT_BASE},
43 {ABI_BASE_LP64S, ABI_EXT_BASE},
44};
45
46/* Initialize enabled_abi_types from TM_MULTILIB_LIST. */
47#ifdef LA_DISABLE_MULTILIB
48#define MULTILIB_LIST_LEN 1
49#else
50#define MULTILIB_LIST_LEN (sizeof (tm_multilib_list) / sizeof (int) / 2)
51static const int tm_multilib_list[] = { TM_MULTILIB_LIST };
52#endif
53static int enabled_abi_types[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES] = { 0 };
54
55#define isa_required(ABI) (abi_minimal_isa[(ABI).base][(ABI).ext])
56extern "C" const struct loongarch_isa
57abi_minimal_isa[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES];
58
59static inline int
60is_multilib_enabled (struct loongarch_abi abi)
61{
62 return enabled_abi_types[abi.base][abi.ext];
63}
64
65static void
66init_enabled_abi_types ()
67{
68#ifdef LA_DISABLE_MULTILIB
69 enabled_abi_types[DEFAULT_ABI_BASE][DEFAULT_ABI_EXT] = 1;
70#else
71 int abi_base, abi_ext;
72 for (unsigned int i = 0; i < MULTILIB_LIST_LEN; i++)
73 {
74 abi_base = tm_multilib_list[i << 1];
75 abi_ext = tm_multilib_list[(i << 1) + 1];
76 enabled_abi_types[abi_base][abi_ext] = 1;
77 }
78#endif
79}
80
b44786f6 81/* String processing. */
82static struct obstack msg_obstack;
83#define APPEND_STRING(STR) obstack_grow (&msg_obstack, STR, strlen(STR));
84#define APPEND1(CH) obstack_1grow(&msg_obstack, CH);
85
86static const char* abi_str (struct loongarch_abi abi);
87static const char* isa_str (const struct loongarch_isa *isa, char separator);
88static const char* arch_str (const struct loongarch_target *target);
89static const char* multilib_enabled_abi_list ();
90
91/* Misc */
92static struct loongarch_abi isa_default_abi (const struct loongarch_isa *isa);
93static int isa_base_compat_p (const struct loongarch_isa *set1,
94 const struct loongarch_isa *set2);
95static int isa_fpu_compat_p (const struct loongarch_isa *set1,
96 const struct loongarch_isa *set2);
97static int abi_compat_p (const struct loongarch_isa *isa,
98 struct loongarch_abi abi);
bb4a8198
YY
99static int abi_default_cpu_arch (struct loongarch_abi abi,
100 struct loongarch_isa *isa);
b44786f6 101
bb4a8198 102/* Mandatory configure-time defaults. */
b44786f6 103#ifndef DEFAULT_ABI_BASE
104#error missing definition of DEFAULT_ABI_BASE in ${tm_defines}.
105#endif
106
107#ifndef DEFAULT_ABI_EXT
108#error missing definition of DEFAULT_ABI_EXT in ${tm_defines}.
109#endif
110
111#ifndef DEFAULT_CPU_ARCH
112#error missing definition of DEFAULT_CPU_ARCH in ${tm_defines}.
113#endif
114
bb4a8198
YY
115/* Optional configure-time defaults. */
116#ifdef DEFAULT_CPU_TUNE
117static int with_default_tune = 1;
118#else
119#define DEFAULT_CPU_TUNE -1
120static int with_default_tune = 0;
121#endif
122
123#ifdef DEFAULT_ISA_EXT_FPU
124static int with_default_fpu = 1;
125#else
126#define DEFAULT_ISA_EXT_FPU -1
127static int with_default_fpu = 0;
128#endif
129
130#ifdef DEFAULT_ISA_EXT_SIMD
131static int with_default_simd = 1;
132#else
133#define DEFAULT_ISA_EXT_SIMD -1
134static int with_default_simd = 0;
b44786f6 135#endif
136
bb4a8198
YY
137
138/* Initialize loongarch_target from separate option variables. */
139
140void
141loongarch_init_target (struct loongarch_target *target,
142 int cpu_arch, int cpu_tune, int fpu, int simd,
143 int abi_base, int abi_ext, int cmodel)
144{
145 if (!target)
146 return;
147 target->cpu_arch = cpu_arch;
148 target->cpu_tune = cpu_tune;
149 target->isa.fpu = fpu;
150 target->isa.simd = simd;
151 target->abi.base = abi_base;
152 target->abi.ext = abi_ext;
153 target->cmodel = cmodel;
154}
155
156
157/* Handle combinations of -m parameters
b44786f6 158 (see loongarch.opt and loongarch-opts.h). */
bb4a8198 159
b44786f6 160void
161loongarch_config_target (struct loongarch_target *target,
bb4a8198
YY
162 struct loongarch_flags *flags,
163 int follow_multilib_list_p)
b44786f6 164{
165 struct loongarch_target t;
2b2a0599 166
b44786f6 167 if (!target)
168 return;
169
170 /* Initialization */
171 init_enabled_abi_types ();
172 obstack_init (&msg_obstack);
173
174 struct {
bb4a8198 175 int arch, tune, fpu, simd, abi_base, abi_ext, cmodel, abi_flt;
b44786f6 176 } constrained = {
bb4a8198
YY
177 M_OPT_ABSENT (target->cpu_arch) ? 0 : 1,
178 M_OPT_ABSENT (target->cpu_tune) ? 0 : 1,
179 M_OPT_ABSENT (target->isa.fpu) ? 0 : 1,
180 M_OPT_ABSENT (target->isa.simd) ? 0 : 1,
181 M_OPT_ABSENT (target->abi.base) ? 0 : 1,
182 M_OPT_ABSENT (target->abi.ext) ? 0 : 1,
183 M_OPT_ABSENT (target->cmodel) ? 0 : 1,
184 M_OPT_ABSENT (target->abi.base) ? 0 : 1,
b44786f6 185 };
186
b44786f6 187 /* 1. Target ABI */
bb4a8198
YY
188 if (constrained.abi_base)
189 t.abi.base = target->abi.base;
190 else
191 t.abi.base = DEFAULT_ABI_BASE;
b44786f6 192
bb4a8198 193 t.abi.ext = constrained.abi_ext ? target->abi.ext : DEFAULT_ABI_EXT;
b44786f6 194
bb4a8198
YY
195 /* Process -m*-float flags */
196 if (flags && !M_OPT_ABSENT (flags->flt))
b44786f6 197 {
bb4a8198
YY
198 /* Modifying the original "target" here makes it easier to write the
199 t.isa.fpu assignment below, because otherwise there would be three
200 levels of precedence (-m*-float / -mfpu / -march) to be handled
201 (now the first two are merged). */
b44786f6 202
bb4a8198 203 target->isa.fpu = flags->flt;
b44786f6 204 constrained.fpu = 1;
205
206 /* The target ISA is not ready yet, but (isa_required (t.abi)
207 + forced fpu) is enough for computing the forced base ABI. */
bb4a8198
YY
208
209 struct loongarch_isa force_isa = isa_required (t.abi);
210 force_isa.fpu = flags->flt;
211
212 struct loongarch_abi force_abi;
b44786f6 213 force_abi.base = isa_default_abi (&force_isa).base;
214
bb4a8198
YY
215 if (constrained.abi_base && constrained.abi_flt
216 && (t.abi.base != force_abi.base))
217 {
218 force_abi.ext = t.abi.ext;
219 inform (UNKNOWN_LOCATION,
220 "%<-m%s%> overrides %<-m%s=%s%>, adjusting ABI to %qs",
221 flags->flt_str, OPTSTR_ABI_BASE,
222 loongarch_abi_base_strings[t.abi.base],
223 abi_str (force_abi));
224 }
b44786f6 225
226 t.abi.base = force_abi.base;
bb4a8198 227 constrained.abi_flt = 1;
b44786f6 228 }
229
230#ifdef LA_DISABLE_MULTILIB
bb4a8198 231 if (follow_multilib_list_p)
b44786f6 232 if (t.abi.base != DEFAULT_ABI_BASE || t.abi.ext != DEFAULT_ABI_EXT)
233 {
234 static const struct loongarch_abi default_abi
235 = {DEFAULT_ABI_BASE, DEFAULT_ABI_EXT};
236
237 warning (0, "ABI changed (%qs to %qs) while multilib is disabled",
238 abi_str (default_abi), abi_str (t.abi));
239 }
240#endif
241
242 /* 2. Target CPU */
bb4a8198
YY
243 t.cpu_arch = constrained.arch ? target->cpu_arch : DEFAULT_CPU_ARCH;
244
245 /* If cpu_tune is not set using neither -mtune nor --with-tune,
246 the current cpu_arch is used as its default. */
247 t.cpu_tune = constrained.tune ? target->cpu_tune
248 : (constrained.arch ? target->cpu_arch :
249 (with_default_tune ? DEFAULT_CPU_TUNE : DEFAULT_CPU_ARCH));
b44786f6 250
b44786f6 251
bb4a8198 252 /* Handle -march/tune=native */
b44786f6 253#ifdef __loongarch__
254 /* For native compilers, gather local CPU information
255 and fill the "CPU_NATIVE" index of arrays defined in
256 loongarch-cpu.c. */
257
bb4a8198 258 fill_native_cpu_config (&t);
b44786f6 259
260#else
261 if (t.cpu_arch == CPU_NATIVE)
262 fatal_error (UNKNOWN_LOCATION,
263 "%qs does not work on a cross compiler",
264 "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE);
265
266 else if (t.cpu_tune == CPU_NATIVE)
267 fatal_error (UNKNOWN_LOCATION,
268 "%qs does not work on a cross compiler",
269 "-m" OPTSTR_TUNE "=" STR_CPU_NATIVE);
270#endif
271
bb4a8198
YY
272 /* Handle -march/tune=abi-default */
273 if (t.cpu_tune == CPU_ABI_DEFAULT)
274 t.cpu_tune = abi_default_cpu_arch (t.abi, NULL);
275
276 if (t.cpu_arch == CPU_ABI_DEFAULT)
277 {
278 t.cpu_arch = abi_default_cpu_arch (t.abi, &(t.isa));
279 loongarch_cpu_default_isa[t.cpu_arch] = t.isa;
280 }
281
282 /* 3. Target base ISA */
b44786f6 283config_target_isa:
284
285 /* Get default ISA from "-march" or its default value. */
bb4a8198 286 t.isa = loongarch_cpu_default_isa[t.cpu_arch];
b44786f6 287
288 /* Apply incremental changes. */
289 /* "-march=native" overrides the default FPU type. */
bb4a8198
YY
290
291 t.isa.fpu = constrained.fpu ? target->isa.fpu :
292 (constrained.arch ? t.isa.fpu :
293 (with_default_fpu ? DEFAULT_ISA_EXT_FPU : t.isa.fpu));
294
295 int simd_base = (constrained.arch ? t.isa.simd :
296 (with_default_simd ? DEFAULT_ISA_EXT_SIMD : t.isa.simd));
297
298 t.isa.simd = constrained.simd ? target->isa.simd : simd_base;
299
300 /* If fallback_lsx is set, using -mno-lasx would cause
301 a fall-back to -msimd=lsx instead of -msimd=none. */
302
303 int fallback_lsx = 0;
304 if (t.isa.simd == ISA_EXT_SIMD_LSX || simd_base != ISA_EXT_NONE)
305 fallback_lsx = 1;
306
307 /* apply -m[no-]lsx and -m[no-]lasx flags */
308 if (flags)
309 for (int i = 0; i < 2; i++)
310 {
311 switch (SX_FLAG_TYPE (flags->sx[i]))
312 {
313 case ISA_EXT_SIMD_LSX:
314 constrained.simd = 1;
315
316 if (flags->sx[i] > 0)
317 fallback_lsx = 1;
318
319 if (flags->sx[i] > 0 && t.isa.simd != ISA_EXT_SIMD_LASX)
320 t.isa.simd = ISA_EXT_SIMD_LSX;
321 else if (flags->sx[i] < 0)
322 t.isa.simd = ISA_EXT_NONE;
323 break;
324
325 case ISA_EXT_SIMD_LASX:
326 constrained.simd = 1;
327 /* If -mlsx or simd=lsx (msimd or march-default) was not
328 involved, do not fall back to simd=lsx. */
329 if (flags->sx[i] < 0 && t.isa.simd == ISA_EXT_SIMD_LASX)
330 t.isa.simd = fallback_lsx ? ISA_EXT_SIMD_LSX : ISA_EXT_NONE;
331 else if (flags->sx[i] > 0)
332 t.isa.simd = ISA_EXT_SIMD_LASX;
333 break;
334
335 case 0:
336 break;
337
338 default:
339 gcc_unreachable ();
340 }
341 }
342
343 /* All SIMD extensions imply a 64-bit FPU:
344 - silently adjust t.isa.fpu to "fpu64" if it is unconstrained.
345 - warn if -msingle-float / -msoft-float is on,
346 then disable SIMD extensions (done in driver)
347 - abort if -mfpu=0 / -mfpu=32 is forced. */
348
349 if (t.isa.simd != ISA_EXT_NONE && t.isa.fpu != ISA_EXT_FPU64)
350 {
351 if (!constrained.fpu)
352 {
353 /* As long as the arch-default "t.isa.simd" is set to non-zero
354 for an element "t" in loongarch_cpu_default_isa, "t.isa.fpu"
355 should be set to "ISA_EXT_FPU64" accordingly. Thus reaching
356 here must be the result of forcing -mlsx/-mlasx explicitly. */
357 gcc_assert (constrained.simd);
358
359 inform (UNKNOWN_LOCATION,
360 "enabing %qs promotes %<%s%s%> to %<%s%s%>",
361 loongarch_isa_ext_strings[t.isa.simd],
362 OPTSTR_ISA_EXT_FPU, loongarch_isa_ext_strings[t.isa.fpu],
363 OPTSTR_ISA_EXT_FPU, loongarch_isa_ext_strings[ISA_EXT_FPU64]);
364
365 t.isa.fpu = ISA_EXT_FPU64;
366 }
367 else if (flags && (flags->flt == ISA_EXT_NONE
368 || flags->flt == ISA_EXT_FPU32))
369 {
370 if (constrained.simd)
371 inform (UNKNOWN_LOCATION,
372 "%qs is disabled by %<-m%s%>, because it requires %<%s%s%>",
373 loongarch_isa_ext_strings[t.isa.simd], flags->flt_str,
374 OPTSTR_ISA_EXT_FPU,
375 loongarch_isa_ext_strings[ISA_EXT_FPU64]);
376
377 t.isa.simd = ISA_EXT_NONE;
378 }
379 else
380 {
381 /* -mfpu=0 / -mfpu=32 is set. */
382 if (constrained.simd)
383 fatal_error (UNKNOWN_LOCATION,
384 "%<-m%s=%s%> conflicts with %qs, "
385 "which requires %<%s%s%>",
386 OPTSTR_ISA_EXT_FPU,
387 loongarch_isa_ext_strings[t.isa.fpu],
388 loongarch_isa_ext_strings[t.isa.simd],
389 OPTSTR_ISA_EXT_FPU,
390 loongarch_isa_ext_strings[ISA_EXT_FPU64]);
391
392 /* Same as above. */
393 t.isa.simd = ISA_EXT_NONE;
394 }
395 }
b44786f6 396
397
398 /* 4. ABI-ISA compatibility */
399 /* Note:
400 - There IS a unique default -march value for each ABI type
401 (config.gcc: triplet -> abi -> default arch).
402
403 - If the base ABI is incompatible with the default arch,
404 try using the default -march it implies (and mark it
405 as "constrained" this time), then re-apply step 3. */
406
407 struct loongarch_abi abi_tmp;
408 const struct loongarch_isa* isa_min;
409
410 abi_tmp = t.abi;
411 isa_min = &isa_required (abi_tmp);
412
413 if (isa_base_compat_p (&t.isa, isa_min)); /* OK. */
414 else if (!constrained.arch)
415 {
416 /* Base architecture can only be implied by -march,
417 so we adjust that first if it is not constrained. */
bb4a8198 418 int fallback_arch = abi_default_cpu_arch (t.abi, NULL);
b44786f6 419
420 if (t.cpu_arch == CPU_NATIVE)
421 warning (0, "your native CPU architecture (%qs) "
422 "does not support %qs ABI, falling back to %<-m%s=%s%>",
423 arch_str (&t), abi_str (t.abi), OPTSTR_ARCH,
424 loongarch_cpu_strings[fallback_arch]);
425 else
426 warning (0, "default CPU architecture (%qs) "
427 "does not support %qs ABI, falling back to %<-m%s=%s%>",
428 arch_str (&t), abi_str (t.abi), OPTSTR_ARCH,
429 loongarch_cpu_strings[fallback_arch]);
430
431 t.cpu_arch = fallback_arch;
432 constrained.arch = 1;
433 goto config_target_isa;
434 }
435 else if (!constrained.abi_base)
436 {
437 /* If -march is given while -mabi is not,
438 try selecting another base ABI type. */
439 abi_tmp.base = isa_default_abi (&t.isa).base;
440 }
441 else
442 goto fatal;
443
444 if (isa_fpu_compat_p (&t.isa, isa_min)); /* OK. */
445 else if (!constrained.fpu)
446 t.isa.fpu = isa_min->fpu;
447 else if (!constrained.abi_base)
448 /* If -march is compatible with the default ABI
449 while -mfpu is not. */
450 abi_tmp.base = isa_default_abi (&t.isa).base;
451 else
452 goto fatal;
453
454 if (0)
455fatal:
456 fatal_error (UNKNOWN_LOCATION,
457 "unable to implement ABI %qs with instruction set %qs",
458 abi_str (t.abi), isa_str (&t.isa, '/'));
459
460
461 /* Using the fallback ABI. */
462 if (abi_tmp.base != t.abi.base || abi_tmp.ext != t.abi.ext)
463 {
464 /* This flag is only set in the GCC driver. */
bb4a8198 465 if (follow_multilib_list_p)
b44786f6 466 {
467
468 /* Continue falling back until we find a feasible ABI type
469 enabled by TM_MULTILIB_LIST. */
470 if (!is_multilib_enabled (abi_tmp))
471 {
472 for (unsigned int i = 0; i < ABI_COUNT; i++)
473 {
474 if (is_multilib_enabled (abi_priority_list[i])
475 && abi_compat_p (&t.isa, abi_priority_list[i]))
476 {
477 abi_tmp = abi_priority_list[i];
478
479 warning (0, "ABI %qs cannot be implemented due to "
480 "limited instruction set %qs, "
481 "falling back to %qs", abi_str (t.abi),
482 isa_str (&t.isa, '/'), abi_str (abi_tmp));
483
484 goto fallback;
485 }
486 }
487
488 /* Otherwise, keep using abi_tmp with a warning. */
489#ifdef LA_DISABLE_MULTILIB
490 warning (0, "instruction set %qs cannot implement "
491 "default ABI %qs, falling back to %qs",
492 isa_str (&t.isa, '/'), abi_str (t.abi),
493 abi_str (abi_tmp));
494#else
495 warning (0, "no multilib-enabled ABI (%qs) can be implemented "
496 "with instruction set %qs, falling back to %qs",
497 multilib_enabled_abi_list (),
498 isa_str (&t.isa, '/'), abi_str (abi_tmp));
499#endif
500 }
501 }
502
503fallback:
504 t.abi = abi_tmp;
505 }
bb4a8198 506 else if (follow_multilib_list_p)
b44786f6 507 {
508 if (!is_multilib_enabled (t.abi))
509 {
510 inform (UNKNOWN_LOCATION,
511 "ABI %qs is not enabled at configure-time, "
512 "the linker might report an error", abi_str (t.abi));
513
514 inform (UNKNOWN_LOCATION, "ABI with startfiles: %s",
515 multilib_enabled_abi_list ());
516 }
517 }
518
519
520 /* 5. Target code model */
bb4a8198 521 t.cmodel = constrained.cmodel ? target->cmodel : CMODEL_NORMAL;
d1028c57
LC
522
523 switch (t.cmodel)
d5e401fb 524 {
d1028c57
LC
525 case CMODEL_TINY:
526 case CMODEL_TINY_STATIC:
527 case CMODEL_LARGE:
5b96c823
LC
528 warning (0, "%qs is not supported, now cmodel is set to %qs",
529 loongarch_cmodel_strings[t.cmodel], "normal");
d5e401fb 530 t.cmodel = CMODEL_NORMAL;
d1028c57
LC
531 break;
532
533 case CMODEL_NORMAL:
534 case CMODEL_MEDIUM:
535 case CMODEL_EXTREME:
536 break;
537
538 default:
539 gcc_unreachable ();
d5e401fb
LC
540 }
541
b44786f6 542 /* Cleanup and return. */
543 obstack_free (&msg_obstack, NULL);
544 *target = t;
545}
546
547/* Returns the default ABI for the given instruction set. */
548static inline struct loongarch_abi
549isa_default_abi (const struct loongarch_isa *isa)
550{
551 struct loongarch_abi abi;
552
553 switch (isa->fpu)
554 {
555 case ISA_EXT_FPU64:
c68463ab 556 if (isa->base >= ISA_BASE_LA64V100)
b44786f6 557 abi.base = ABI_BASE_LP64D;
558 break;
559
560 case ISA_EXT_FPU32:
c68463ab 561 if (isa->base >= ISA_BASE_LA64V100)
b44786f6 562 abi.base = ABI_BASE_LP64F;
563 break;
564
bb4a8198 565 case ISA_EXT_NONE:
c68463ab 566 if (isa->base >= ISA_BASE_LA64V100)
b44786f6 567 abi.base = ABI_BASE_LP64S;
568 break;
569
570 default:
571 gcc_unreachable ();
572 }
573
574 abi.ext = ABI_EXT_BASE;
575 return abi;
576}
577
578/* Check if set2 is a subset of set1. */
579static inline int
580isa_base_compat_p (const struct loongarch_isa *set1,
581 const struct loongarch_isa *set2)
582{
583 switch (set2->base)
584 {
585 case ISA_BASE_LA64V100:
c68463ab 586 return (set1->base >= ISA_BASE_LA64V100);
b44786f6 587
588 default:
589 gcc_unreachable ();
590 }
591}
592
593static inline int
594isa_fpu_compat_p (const struct loongarch_isa *set1,
595 const struct loongarch_isa *set2)
596{
597 switch (set2->fpu)
598 {
599 case ISA_EXT_FPU64:
600 return set1->fpu == ISA_EXT_FPU64;
601
602 case ISA_EXT_FPU32:
603 return set1->fpu == ISA_EXT_FPU32 || set1->fpu == ISA_EXT_FPU64;
604
bb4a8198 605 case ISA_EXT_NONE:
b44786f6 606 return 1;
607
608 default:
609 gcc_unreachable ();
610 }
611
612}
613
614static inline int
615abi_compat_p (const struct loongarch_isa *isa, struct loongarch_abi abi)
616{
617 int compatible = 1;
618 const struct loongarch_isa *isa2 = &isa_required (abi);
619
620 /* Append conditionals for new ISA components below. */
621 compatible = compatible && isa_base_compat_p (isa, isa2);
622 compatible = compatible && isa_fpu_compat_p (isa, isa2);
623 return compatible;
624}
625
626/* The behavior of this function should be consistent
627 with config.gcc. */
628static inline int
bb4a8198
YY
629abi_default_cpu_arch (struct loongarch_abi abi,
630 struct loongarch_isa *isa)
b44786f6 631{
bb4a8198
YY
632 static struct loongarch_isa tmp;
633 if (!isa)
634 isa = &tmp;
635
636 if (abi.ext == ABI_EXT_BASE)
637 switch (abi.base)
638 {
639 case ABI_BASE_LP64D:
640 case ABI_BASE_LP64F:
641 case ABI_BASE_LP64S:
642 *isa = isa_required (abi);
b44786f6 643 return CPU_LOONGARCH64;
bb4a8198 644 }
b44786f6 645 gcc_unreachable ();
646}
647
648static const char*
649abi_str (struct loongarch_abi abi)
650{
651 /* "/base" can be omitted. */
652 if (abi.ext == ABI_EXT_BASE)
653 return (const char*)
654 obstack_copy0 (&msg_obstack, loongarch_abi_base_strings[abi.base],
655 strlen (loongarch_abi_base_strings[abi.base]));
656 else
657 {
2b2a0599
XR
658 /* This situation has not yet occurred, so in order to avoid the
659 -Warray-bounds warning during C++ syntax checking, this part
660 of the code is commented first. */
661 /*
b44786f6 662 APPEND_STRING (loongarch_abi_base_strings[abi.base])
663 APPEND1 ('/')
664 APPEND_STRING (loongarch_abi_ext_strings[abi.ext])
665 APPEND1 ('\0')
666
667 return XOBFINISH (&msg_obstack, const char *);
2b2a0599
XR
668 */
669 gcc_unreachable ();
b44786f6 670 }
671}
672
673static const char*
674isa_str (const struct loongarch_isa *isa, char separator)
675{
676 APPEND_STRING (loongarch_isa_base_strings[isa->base])
677 APPEND1 (separator)
678
bb4a8198 679 if (isa->fpu == ISA_EXT_NONE)
b44786f6 680 {
681 APPEND_STRING ("no" OPTSTR_ISA_EXT_FPU)
682 }
683 else
684 {
685 APPEND_STRING (OPTSTR_ISA_EXT_FPU)
686 APPEND_STRING (loongarch_isa_ext_strings[isa->fpu])
687 }
bb4a8198
YY
688
689 switch (isa->simd)
690 {
691 case ISA_EXT_SIMD_LSX:
692 case ISA_EXT_SIMD_LASX:
693 APPEND1 (separator);
694 APPEND_STRING (loongarch_isa_ext_strings[isa->simd]);
695 break;
696
697 default:
698 gcc_assert (isa->simd == 0);
699 }
b44786f6 700 APPEND1 ('\0')
701
702 /* Add more here. */
703
704 return XOBFINISH (&msg_obstack, const char *);
705}
706
707static const char*
708arch_str (const struct loongarch_target *target)
709{
710 if (target->cpu_arch == CPU_NATIVE)
711 {
bb4a8198
YY
712 /* Describe a native CPU with unknown PRID. */
713 const char* isa_string = isa_str (&target->isa, ',');
714 APPEND_STRING ("PRID: 0x")
715 APPEND_STRING (get_native_prid_str ())
716 APPEND_STRING (", ISA features: ")
717 APPEND_STRING (isa_string)
b44786f6 718 }
719 else
720 APPEND_STRING (loongarch_cpu_strings[target->cpu_arch]);
721
722 APPEND1 ('\0')
723 return XOBFINISH (&msg_obstack, const char *);
724}
725
726static const char*
727multilib_enabled_abi_list ()
728{
729 int enabled_abi_idx[MULTILIB_LIST_LEN] = { 0 };
730 const char* enabled_abi_str[MULTILIB_LIST_LEN] = { NULL };
731 unsigned int j = 0;
732
733 for (unsigned int i = 0; i < ABI_COUNT && j < MULTILIB_LIST_LEN; i++)
734 {
735 if (enabled_abi_types[abi_priority_list[i].base]
736 [abi_priority_list[i].ext])
737 {
738 enabled_abi_idx[j++] = i;
739 }
740 }
741
742 for (unsigned int k = 0; k < j; k++)
743 {
744 enabled_abi_str[k] = abi_str (abi_priority_list[enabled_abi_idx[k]]);
745 }
746
747 for (unsigned int k = 0; k < j - 1; k++)
748 {
749 APPEND_STRING (enabled_abi_str[k])
750 APPEND1 (',')
751 APPEND1 (' ')
752 }
753 APPEND_STRING (enabled_abi_str[j - 1])
754 APPEND1 ('\0')
755
756 return XOBFINISH (&msg_obstack, const char *);
757}
bb4a8198
YY
758
759/* option status feedback for "gcc --help=target -Q" */
760void
761loongarch_update_gcc_opt_status (struct loongarch_target *target,
762 struct gcc_options *opts,
763 struct gcc_options *opts_set)
764{
765 (void) opts_set;
766
767 /* status of -mabi */
768 opts->x_la_opt_abi_base = target->abi.base;
769
770 /* status of -march and -mtune */
771 opts->x_la_opt_cpu_arch = target->cpu_arch;
772 opts->x_la_opt_cpu_tune = target->cpu_tune;
773
774 /* status of -mfpu */
775 opts->x_la_opt_fpu = target->isa.fpu;
776 opts->x_la_opt_simd = target->isa.simd;
777}