loongarch-opts.cc revision 1.1 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