136ac495dSmrg /* Common hooks for ARM.
2*8feb0f0bSmrg Copyright (C) 1991-2020 Free Software Foundation, Inc.
336ac495dSmrg
436ac495dSmrg This file is part of GCC.
536ac495dSmrg
636ac495dSmrg GCC is free software; you can redistribute it and/or modify it
736ac495dSmrg under the terms of the GNU General Public License as published
836ac495dSmrg by the Free Software Foundation; either version 3, or (at your
936ac495dSmrg option) any later version.
1036ac495dSmrg
1136ac495dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT
1236ac495dSmrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1336ac495dSmrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1436ac495dSmrg License for more details.
1536ac495dSmrg
1636ac495dSmrg You should have received a copy of the GNU General Public License
1736ac495dSmrg along with GCC; see the file COPYING3. If not see
1836ac495dSmrg <http://www.gnu.org/licenses/>. */
1936ac495dSmrg
20a2dc1f3fSmrg #define INCLUDE_LIST
21a2dc1f3fSmrg #define INCLUDE_VECTOR
2236ac495dSmrg #include "config.h"
2336ac495dSmrg #include "system.h"
2436ac495dSmrg #include "coretypes.h"
2536ac495dSmrg #include "tm.h"
2636ac495dSmrg #include "memmodel.h"
2736ac495dSmrg #include "tm_p.h"
2836ac495dSmrg #include "common/common-target.h"
2936ac495dSmrg #include "common/common-target-def.h"
3036ac495dSmrg #include "opts.h"
3136ac495dSmrg #include "flags.h"
32a2dc1f3fSmrg #include "sbitmap.h"
33a2dc1f3fSmrg #include "diagnostic.h"
34a2dc1f3fSmrg #include <algorithm>
3536ac495dSmrg
3636ac495dSmrg /* Set default optimization options. */
3736ac495dSmrg static const struct default_options arm_option_optimization_table[] =
3836ac495dSmrg {
3936ac495dSmrg /* Enable section anchors by default at -O1 or higher. */
4036ac495dSmrg { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
4136ac495dSmrg { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 },
4236ac495dSmrg { OPT_LEVELS_NONE, 0, NULL, 0 }
4336ac495dSmrg };
4436ac495dSmrg
4536ac495dSmrg /* Implement TARGET_EXCEPT_UNWIND_INFO. */
4636ac495dSmrg
4736ac495dSmrg enum unwind_info_type
arm_except_unwind_info(struct gcc_options * opts)4836ac495dSmrg arm_except_unwind_info (struct gcc_options *opts)
4936ac495dSmrg {
5036ac495dSmrg /* Honor the --enable-sjlj-exceptions configure switch. */
5136ac495dSmrg #ifdef CONFIG_SJLJ_EXCEPTIONS
5236ac495dSmrg if (CONFIG_SJLJ_EXCEPTIONS)
5336ac495dSmrg return UI_SJLJ;
5436ac495dSmrg #endif
5536ac495dSmrg
5636ac495dSmrg if (ARM_DWARF_UNWIND_TABLES)
5736ac495dSmrg return UI_DWARF2;
5836ac495dSmrg
5936ac495dSmrg /* If not using ARM EABI unwind tables... */
6036ac495dSmrg if (ARM_UNWIND_INFO)
6136ac495dSmrg {
6236ac495dSmrg /* For simplicity elsewhere in this file, indicate that all unwind
6336ac495dSmrg info is disabled if we're not emitting unwind tables. */
6436ac495dSmrg if (!opts->x_flag_exceptions && !opts->x_flag_unwind_tables)
6536ac495dSmrg return UI_NONE;
6636ac495dSmrg else
6736ac495dSmrg return UI_TARGET;
6836ac495dSmrg }
6936ac495dSmrg
70a2dc1f3fSmrg /* ... honor target configurations requesting DWARF2 EH... */
71a2dc1f3fSmrg #ifdef DWARF2_UNWIND_INFO
72a2dc1f3fSmrg if (DWARF2_UNWIND_INFO)
73a2dc1f3fSmrg return UI_DWARF2;
74a2dc1f3fSmrg #endif
75a2dc1f3fSmrg
76a2dc1f3fSmrg /* ... or fallback to sjlj exceptions for backwards compatibility. */
7736ac495dSmrg return UI_SJLJ;
7836ac495dSmrg }
7936ac495dSmrg
8036ac495dSmrg #define ARM_CPU_NAME_LENGTH 20
8136ac495dSmrg
82a2dc1f3fSmrg /* Truncate NAME at the first '.' or '+' character seen, or return
8336ac495dSmrg NAME unmodified. */
8436ac495dSmrg
8536ac495dSmrg const char *
arm_rewrite_selected_cpu(const char * name)8636ac495dSmrg arm_rewrite_selected_cpu (const char *name)
8736ac495dSmrg {
8836ac495dSmrg static char output_buf[ARM_CPU_NAME_LENGTH + 1] = {0};
8936ac495dSmrg char *arg_pos;
9036ac495dSmrg
9136ac495dSmrg strncpy (output_buf, name, ARM_CPU_NAME_LENGTH);
92a2dc1f3fSmrg output_buf[ARM_CPU_NAME_LENGTH] = 0;
93a2dc1f3fSmrg
9436ac495dSmrg arg_pos = strchr (output_buf, '.');
9536ac495dSmrg
9636ac495dSmrg /* If we found a '.' truncate the entry at that point. */
9736ac495dSmrg if (arg_pos)
9836ac495dSmrg *arg_pos = '\0';
9936ac495dSmrg
100a2dc1f3fSmrg arg_pos = strchr (output_buf, '+');
101a2dc1f3fSmrg
102a2dc1f3fSmrg /* If we found a '+' truncate the entry at that point. */
103a2dc1f3fSmrg if (arg_pos)
104a2dc1f3fSmrg *arg_pos = '\0';
105a2dc1f3fSmrg
10636ac495dSmrg return output_buf;
10736ac495dSmrg }
10836ac495dSmrg
10936ac495dSmrg /* Called by the driver to rewrite a name passed to the -mcpu
11036ac495dSmrg argument in preparation to be passed to the assembler. The
11136ac495dSmrg names passed from the command line will be in ARGV, we want
11236ac495dSmrg to use the right-most argument, which should be in
11336ac495dSmrg ARGV[ARGC - 1]. ARGC should always be greater than 0. */
11436ac495dSmrg
11536ac495dSmrg const char *
arm_rewrite_mcpu(int argc,const char ** argv)11636ac495dSmrg arm_rewrite_mcpu (int argc, const char **argv)
11736ac495dSmrg {
11836ac495dSmrg gcc_assert (argc);
11936ac495dSmrg return arm_rewrite_selected_cpu (argv[argc - 1]);
12036ac495dSmrg }
12136ac495dSmrg
122a2dc1f3fSmrg /* Comparator for arm_rewrite_selected_arch. Compare the two arch extension
123a2dc1f3fSmrg strings FIRST and SECOND and return TRUE if FIRST is less than SECOND
124a2dc1f3fSmrg alphabetically. */
12536ac495dSmrg
126a2dc1f3fSmrg static bool
compare_opt_names(const char * first,const char * second)127a2dc1f3fSmrg compare_opt_names (const char *first, const char *second)
128a2dc1f3fSmrg {
129a2dc1f3fSmrg return strcmp (first, second) <= 0;
130a2dc1f3fSmrg }
131a2dc1f3fSmrg
132a2dc1f3fSmrg /* Rewrite the architecture string for passing to the assembler.
133a2dc1f3fSmrg Although the syntax is similar we cannot assume that it supports
134a2dc1f3fSmrg the newer FP related options. So strip any option that only
135a2dc1f3fSmrg defines features in the standard -mfpu options out. We'll generate
136a2dc1f3fSmrg a suitable -mfpu option elsewhere to carry that information. NAME
137a2dc1f3fSmrg should already have been canonicalized, so we do not expect to
138a2dc1f3fSmrg encounter +no.. options that remove features. A final problem is
139a2dc1f3fSmrg that the assembler expects the feature extensions to be listed
140a2dc1f3fSmrg alphabetically, so we build a list of required options and then
141a2dc1f3fSmrg sort them into canonical order in the resulting string. */
142a2dc1f3fSmrg const char *
arm_rewrite_selected_arch(const char * name)143a2dc1f3fSmrg arm_rewrite_selected_arch (const char *name)
144a2dc1f3fSmrg {
145a2dc1f3fSmrg /* The result we return needs to be semi persistent, so handle being
146a2dc1f3fSmrg re-invoked. */
147a2dc1f3fSmrg static char *asm_arch = NULL;
148a2dc1f3fSmrg
149a2dc1f3fSmrg if (asm_arch)
150a2dc1f3fSmrg {
151a2dc1f3fSmrg free (asm_arch);
152a2dc1f3fSmrg asm_arch = NULL;
153a2dc1f3fSmrg }
154a2dc1f3fSmrg
155a2dc1f3fSmrg const char *arg_pos = strchr (name, '+');
156a2dc1f3fSmrg
157a2dc1f3fSmrg /* No extension options? just return the original string. */
158a2dc1f3fSmrg if (arg_pos == NULL)
159a2dc1f3fSmrg return name;
160a2dc1f3fSmrg
161a2dc1f3fSmrg const arch_option *arch_opt
162a2dc1f3fSmrg = arm_parse_arch_option_name (all_architectures, "-march", name);
163a2dc1f3fSmrg
164a2dc1f3fSmrg auto_sbitmap fpu_bits (isa_num_bits);
165a2dc1f3fSmrg static const enum isa_feature fpu_bitlist[]
166a2dc1f3fSmrg = { ISA_ALL_FPU_INTERNAL, isa_nobit };
167a2dc1f3fSmrg
168a2dc1f3fSmrg arm_initialize_isa (fpu_bits, fpu_bitlist);
169a2dc1f3fSmrg
170a2dc1f3fSmrg auto_sbitmap opt_bits (isa_num_bits);
171a2dc1f3fSmrg
172a2dc1f3fSmrg /* Ensure that the resulting string is large enough for the result. We
173a2dc1f3fSmrg never add options, so using strdup here will ensure that. */
174a2dc1f3fSmrg asm_arch = xstrdup (name);
175a2dc1f3fSmrg asm_arch[arg_pos - name] = '\0';
176a2dc1f3fSmrg
177a2dc1f3fSmrg std::vector<const char *>optlist;
178a2dc1f3fSmrg
179a2dc1f3fSmrg while (arg_pos)
180a2dc1f3fSmrg {
181a2dc1f3fSmrg const char *end = strchr (arg_pos + 1, '+');
182a2dc1f3fSmrg size_t len = end ? end - arg_pos : strlen (arg_pos);
183a2dc1f3fSmrg
184a2dc1f3fSmrg for (const cpu_arch_extension *entry = arch_opt->common.extensions;
185a2dc1f3fSmrg entry->name != NULL;
186a2dc1f3fSmrg entry++)
187a2dc1f3fSmrg {
188a2dc1f3fSmrg if (strncmp (entry->name, arg_pos + 1, len - 1) == 0
189a2dc1f3fSmrg && entry->name[len - 1] == '\0')
190a2dc1f3fSmrg {
191a2dc1f3fSmrg /* Don't expect removal options. */
192a2dc1f3fSmrg gcc_assert (!entry->remove);
193a2dc1f3fSmrg arm_initialize_isa (opt_bits, entry->isa_bits);
194a2dc1f3fSmrg if (!bitmap_subset_p (opt_bits, fpu_bits))
195a2dc1f3fSmrg optlist.push_back (entry->name);
196a2dc1f3fSmrg bitmap_clear (opt_bits);
197a2dc1f3fSmrg break;
198a2dc1f3fSmrg }
199a2dc1f3fSmrg }
200a2dc1f3fSmrg
201a2dc1f3fSmrg arg_pos = end;
202a2dc1f3fSmrg }
203a2dc1f3fSmrg
204a2dc1f3fSmrg std::sort (optlist.begin (), optlist.end (), compare_opt_names);
205a2dc1f3fSmrg
206a2dc1f3fSmrg for (std::vector<const char *>::iterator opt_iter = optlist.begin ();
207a2dc1f3fSmrg opt_iter != optlist.end ();
208a2dc1f3fSmrg ++opt_iter)
209a2dc1f3fSmrg {
210a2dc1f3fSmrg strcat (asm_arch, "+");
211a2dc1f3fSmrg strcat (asm_arch, (*opt_iter));
212a2dc1f3fSmrg }
213a2dc1f3fSmrg
214a2dc1f3fSmrg return asm_arch;
215a2dc1f3fSmrg }
216a2dc1f3fSmrg
217a2dc1f3fSmrg /* Called by the driver to rewrite a name passed to the -march
218a2dc1f3fSmrg argument in preparation to be passed to the assembler. The
219a2dc1f3fSmrg names passed from the command line will be in ARGV, we want
220a2dc1f3fSmrg to use the right-most argument, which should be in
221a2dc1f3fSmrg ARGV[ARGC - 1]. ARGC should always be greater than 0. */
222a2dc1f3fSmrg
223a2dc1f3fSmrg const char *
arm_rewrite_march(int argc,const char ** argv)224a2dc1f3fSmrg arm_rewrite_march (int argc, const char **argv)
225a2dc1f3fSmrg {
226a2dc1f3fSmrg gcc_assert (argc);
227a2dc1f3fSmrg return arm_rewrite_selected_arch (argv[argc - 1]);
228a2dc1f3fSmrg }
229a2dc1f3fSmrg
230a2dc1f3fSmrg #include "arm-cpu-cdata.h"
23136ac495dSmrg
23236ac495dSmrg /* Scan over a raw feature array BITS checking for BIT being present.
23336ac495dSmrg This is slower than the normal bitmask checks, but we would spend longer
23436ac495dSmrg initializing that than doing the check this way. Returns true iff
23536ac495dSmrg BIT is found. */
23636ac495dSmrg static bool
check_isa_bits_for(const enum isa_feature * bits,enum isa_feature bit)23736ac495dSmrg check_isa_bits_for (const enum isa_feature* bits, enum isa_feature bit)
23836ac495dSmrg {
23936ac495dSmrg while (*bits != isa_nobit)
24036ac495dSmrg if (*bits++ == bit)
24136ac495dSmrg return true;
24236ac495dSmrg
24336ac495dSmrg return false;
24436ac495dSmrg }
24536ac495dSmrg
24636ac495dSmrg /* Called by the driver to check whether the target denoted by current
24736ac495dSmrg command line options is a Thumb-only target. ARGV is an array of
248a2dc1f3fSmrg tupples (normally only one) where the first element of the tupple
249a2dc1f3fSmrg is 'cpu' or 'arch' and the second is the option passed to the
250a2dc1f3fSmrg compiler for that. An architecture tupple is always taken in
251a2dc1f3fSmrg preference to a cpu tupple and the last of each type always
252a2dc1f3fSmrg overrides any earlier setting. */
253a2dc1f3fSmrg
25436ac495dSmrg const char *
arm_target_thumb_only(int argc,const char ** argv)25536ac495dSmrg arm_target_thumb_only (int argc, const char **argv)
25636ac495dSmrg {
257a2dc1f3fSmrg const char *arch = NULL;
258a2dc1f3fSmrg const char *cpu = NULL;
25936ac495dSmrg
260a2dc1f3fSmrg if (argc % 2 != 0)
261a2dc1f3fSmrg fatal_error (input_location,
262a2dc1f3fSmrg "%%:target_mode_check takes an even number of parameters");
263a2dc1f3fSmrg
264a2dc1f3fSmrg while (argc)
26536ac495dSmrg {
266a2dc1f3fSmrg if (strcmp (argv[0], "arch") == 0)
267a2dc1f3fSmrg arch = argv[1];
268a2dc1f3fSmrg else if (strcmp (argv[0], "cpu") == 0)
269a2dc1f3fSmrg cpu = argv[1];
270a2dc1f3fSmrg else
271a2dc1f3fSmrg fatal_error (input_location,
272a2dc1f3fSmrg "unrecognized option passed to %%:target_mode_check");
273a2dc1f3fSmrg argc -= 2;
274a2dc1f3fSmrg argv += 2;
275a2dc1f3fSmrg }
276a2dc1f3fSmrg
277a2dc1f3fSmrg /* No architecture, or CPU, has option extensions that change
278a2dc1f3fSmrg whether or not we have a Thumb-only device, so there is no need
279a2dc1f3fSmrg to scan any option extensions specified. */
280a2dc1f3fSmrg
281a2dc1f3fSmrg /* If the architecture is specified, that overrides any CPU setting. */
282a2dc1f3fSmrg if (arch)
283a2dc1f3fSmrg {
284a2dc1f3fSmrg const arch_option *arch_opt
285a2dc1f3fSmrg = arm_parse_arch_option_name (all_architectures, "-march", arch,
286a2dc1f3fSmrg false);
287a2dc1f3fSmrg
288a2dc1f3fSmrg if (arch_opt && !check_isa_bits_for (arch_opt->common.isa_bits,
28936ac495dSmrg isa_bit_notm))
29036ac495dSmrg return "-mthumb";
291a2dc1f3fSmrg }
292a2dc1f3fSmrg else if (cpu)
293a2dc1f3fSmrg {
294a2dc1f3fSmrg const cpu_option *cpu_opt
295a2dc1f3fSmrg = arm_parse_cpu_option_name (all_cores, "-mcpu", cpu, false);
29636ac495dSmrg
297a2dc1f3fSmrg if (cpu_opt && !check_isa_bits_for (cpu_opt->common.isa_bits,
298a2dc1f3fSmrg isa_bit_notm))
299a2dc1f3fSmrg return "-mthumb";
300a2dc1f3fSmrg }
301a2dc1f3fSmrg
302a2dc1f3fSmrg /* Compiler hasn't been configured with a default, and the CPU
303a2dc1f3fSmrg doesn't require Thumb, so default to ARM. */
304a2dc1f3fSmrg return "-marm";
305a2dc1f3fSmrg }
306a2dc1f3fSmrg
307a2dc1f3fSmrg /* List the permitted CPU option names. If TARGET is a near miss for an
308a2dc1f3fSmrg entry, print out the suggested alternative. */
309a2dc1f3fSmrg static void
arm_print_hint_for_cpu_option(const char * target,const cpu_option * list)310a2dc1f3fSmrg arm_print_hint_for_cpu_option (const char *target,
311a2dc1f3fSmrg const cpu_option *list)
312a2dc1f3fSmrg {
313a2dc1f3fSmrg auto_vec<const char*> candidates;
314a2dc1f3fSmrg for (; list->common.name != NULL; list++)
315c0a68be4Smrg {
316a2dc1f3fSmrg candidates.safe_push (list->common.name);
317c0a68be4Smrg if (list->aliases)
318c0a68be4Smrg {
319c0a68be4Smrg for (const cpu_alias *alias = list->aliases; alias->name != NULL;
320c0a68be4Smrg alias++)
321c0a68be4Smrg if (alias->visible)
322c0a68be4Smrg candidates.safe_push (alias->name);
323c0a68be4Smrg }
324c0a68be4Smrg }
325a2dc1f3fSmrg
326a2dc1f3fSmrg #ifdef HAVE_LOCAL_CPU_DETECT
327a2dc1f3fSmrg /* Add also "native" as possible value. */
328a2dc1f3fSmrg candidates.safe_push ("native");
329a2dc1f3fSmrg #endif
330a2dc1f3fSmrg
331a2dc1f3fSmrg char *s;
332a2dc1f3fSmrg const char *hint = candidates_list_and_hint (target, s, candidates);
333a2dc1f3fSmrg if (hint)
334a2dc1f3fSmrg inform (input_location, "valid arguments are: %s; did you mean %qs?",
335a2dc1f3fSmrg s, hint);
336a2dc1f3fSmrg else
337a2dc1f3fSmrg inform (input_location, "valid arguments are: %s", s);
338a2dc1f3fSmrg
339a2dc1f3fSmrg XDELETEVEC (s);
340a2dc1f3fSmrg }
341a2dc1f3fSmrg
342a2dc1f3fSmrg /* Parse the base component of a CPU selection in LIST. Return a
343a2dc1f3fSmrg pointer to the entry in the architecture table. OPTNAME is the
344a2dc1f3fSmrg name of the option we are parsing and can be used if a diagnostic
345a2dc1f3fSmrg is needed. If COMPLAIN is true (the default) emit error
346a2dc1f3fSmrg messages and hints on invalid input. */
347a2dc1f3fSmrg const cpu_option *
arm_parse_cpu_option_name(const cpu_option * list,const char * optname,const char * target,bool complain)348a2dc1f3fSmrg arm_parse_cpu_option_name (const cpu_option *list, const char *optname,
349a2dc1f3fSmrg const char *target, bool complain)
350a2dc1f3fSmrg {
351a2dc1f3fSmrg const cpu_option *entry;
352a2dc1f3fSmrg const char *end = strchr (target, '+');
353a2dc1f3fSmrg size_t len = end ? end - target : strlen (target);
354a2dc1f3fSmrg
355a2dc1f3fSmrg for (entry = list; entry->common.name != NULL; entry++)
356a2dc1f3fSmrg {
357a2dc1f3fSmrg if (strncmp (entry->common.name, target, len) == 0
358a2dc1f3fSmrg && entry->common.name[len] == '\0')
359a2dc1f3fSmrg return entry;
360c0a68be4Smrg
361c0a68be4Smrg /* Match against any legal alias for this CPU candidate. */
362c0a68be4Smrg if (entry->aliases)
363c0a68be4Smrg {
364c0a68be4Smrg for (const cpu_alias *alias = entry->aliases; alias->name != NULL;
365c0a68be4Smrg alias++)
366c0a68be4Smrg if (strncmp (alias->name, target, len) == 0
367c0a68be4Smrg && alias->name[len] == '\0')
368c0a68be4Smrg return entry;
369c0a68be4Smrg }
370a2dc1f3fSmrg }
371a2dc1f3fSmrg
372a2dc1f3fSmrg if (complain)
373a2dc1f3fSmrg {
374a2dc1f3fSmrg error_at (input_location, "unrecognized %s target: %s", optname, target);
375a2dc1f3fSmrg arm_print_hint_for_cpu_option (target, list);
376a2dc1f3fSmrg }
37736ac495dSmrg return NULL;
37836ac495dSmrg }
379a2dc1f3fSmrg
380a2dc1f3fSmrg /* List the permitted architecture option names. If TARGET is a near
381a2dc1f3fSmrg miss for an entry, print out the suggested alternative. */
382a2dc1f3fSmrg static void
arm_print_hint_for_arch_option(const char * target,const arch_option * list)383a2dc1f3fSmrg arm_print_hint_for_arch_option (const char *target,
384a2dc1f3fSmrg const arch_option *list)
385a2dc1f3fSmrg {
386a2dc1f3fSmrg auto_vec<const char*> candidates;
387a2dc1f3fSmrg for (; list->common.name != NULL; list++)
388a2dc1f3fSmrg candidates.safe_push (list->common.name);
389a2dc1f3fSmrg
390a2dc1f3fSmrg #ifdef HAVE_LOCAL_CPU_DETECT
391a2dc1f3fSmrg /* Add also "native" as possible value. */
392a2dc1f3fSmrg candidates.safe_push ("native");
393a2dc1f3fSmrg #endif
394a2dc1f3fSmrg
395a2dc1f3fSmrg char *s;
396a2dc1f3fSmrg const char *hint = candidates_list_and_hint (target, s, candidates);
397a2dc1f3fSmrg if (hint)
398a2dc1f3fSmrg inform (input_location, "valid arguments are: %s; did you mean %qs?",
399a2dc1f3fSmrg s, hint);
40036ac495dSmrg else
401a2dc1f3fSmrg inform (input_location, "valid arguments are: %s", s);
402a2dc1f3fSmrg
403a2dc1f3fSmrg XDELETEVEC (s);
404a2dc1f3fSmrg }
405a2dc1f3fSmrg
406a2dc1f3fSmrg /* Parse the base component of a CPU or architecture selection in
407a2dc1f3fSmrg LIST. Return a pointer to the entry in the architecture table.
408a2dc1f3fSmrg OPTNAME is the name of the option we are parsing and can be used if
409a2dc1f3fSmrg a diagnostic is needed. If COMPLAIN is true (the default) emit error
410a2dc1f3fSmrg messages and hints on invalid input. */
411a2dc1f3fSmrg const arch_option *
arm_parse_arch_option_name(const arch_option * list,const char * optname,const char * target,bool complain)412a2dc1f3fSmrg arm_parse_arch_option_name (const arch_option *list, const char *optname,
413a2dc1f3fSmrg const char *target, bool complain)
414a2dc1f3fSmrg {
415a2dc1f3fSmrg const arch_option *entry;
416a2dc1f3fSmrg const char *end = strchr (target, '+');
417a2dc1f3fSmrg size_t len = end ? end - target : strlen (target);
418a2dc1f3fSmrg
419a2dc1f3fSmrg for (entry = list; entry->common.name != NULL; entry++)
420a2dc1f3fSmrg {
421a2dc1f3fSmrg if (strncmp (entry->common.name, target, len) == 0
422a2dc1f3fSmrg && entry->common.name[len] == '\0')
423a2dc1f3fSmrg return entry;
424a2dc1f3fSmrg }
425a2dc1f3fSmrg
426a2dc1f3fSmrg if (complain)
427a2dc1f3fSmrg {
428a2dc1f3fSmrg error_at (input_location, "unrecognized %s target: %s", optname, target);
429a2dc1f3fSmrg arm_print_hint_for_arch_option (target, list);
430a2dc1f3fSmrg }
43136ac495dSmrg return NULL;
43236ac495dSmrg }
43336ac495dSmrg
434a2dc1f3fSmrg /* List the permitted architecture option names. If TARGET is a near
435a2dc1f3fSmrg miss for an entry, print out the suggested alternative. */
436a2dc1f3fSmrg static void
arm_print_hint_for_fpu_option(const char * target)437a2dc1f3fSmrg arm_print_hint_for_fpu_option (const char *target)
438a2dc1f3fSmrg {
439a2dc1f3fSmrg auto_vec<const char*> candidates;
440a2dc1f3fSmrg for (int i = 0; i < TARGET_FPU_auto; i++)
441a2dc1f3fSmrg candidates.safe_push (all_fpus[i].name);
442a2dc1f3fSmrg char *s;
443a2dc1f3fSmrg const char *hint = candidates_list_and_hint (target, s, candidates);
444a2dc1f3fSmrg if (hint)
445a2dc1f3fSmrg inform (input_location, "valid arguments are: %s; did you mean %qs?",
446a2dc1f3fSmrg s, hint);
447a2dc1f3fSmrg else
448a2dc1f3fSmrg inform (input_location, "valid arguments are: %s", s);
449a2dc1f3fSmrg
450a2dc1f3fSmrg XDELETEVEC (s);
451a2dc1f3fSmrg }
452a2dc1f3fSmrg
453a2dc1f3fSmrg static const arm_fpu_desc *
arm_parse_fpu_option(const char * opt)454a2dc1f3fSmrg arm_parse_fpu_option (const char *opt)
455a2dc1f3fSmrg {
456a2dc1f3fSmrg int i;
457a2dc1f3fSmrg
458a2dc1f3fSmrg for (i = 0; i < TARGET_FPU_auto; i++)
459a2dc1f3fSmrg {
460a2dc1f3fSmrg if (strcmp (all_fpus[i].name, opt) == 0)
461a2dc1f3fSmrg return all_fpus + i;
462a2dc1f3fSmrg }
463a2dc1f3fSmrg
464c0a68be4Smrg error_at (input_location, "unrecognized %<-mfpu%> target: %s", opt);
465a2dc1f3fSmrg arm_print_hint_for_fpu_option (opt);
466a2dc1f3fSmrg return NULL;
467a2dc1f3fSmrg }
468a2dc1f3fSmrg
469a2dc1f3fSmrg /* Convert a static initializer array of feature bits to sbitmap
470a2dc1f3fSmrg representation. */
471a2dc1f3fSmrg void
arm_initialize_isa(sbitmap isa,const enum isa_feature * isa_bits)472a2dc1f3fSmrg arm_initialize_isa (sbitmap isa, const enum isa_feature *isa_bits)
473a2dc1f3fSmrg {
474a2dc1f3fSmrg bitmap_clear (isa);
475a2dc1f3fSmrg while (*isa_bits != isa_nobit)
476a2dc1f3fSmrg bitmap_set_bit (isa, *(isa_bits++));
477a2dc1f3fSmrg }
478a2dc1f3fSmrg
479a2dc1f3fSmrg /* OPT isn't a recognized feature. Print a suitable error message and
480a2dc1f3fSmrg suggest a possible value. Always print the list of permitted
481a2dc1f3fSmrg values. */
482a2dc1f3fSmrg static void
arm_unrecognized_feature(const char * opt,size_t len,const cpu_arch_option * target)483a2dc1f3fSmrg arm_unrecognized_feature (const char *opt, size_t len,
484a2dc1f3fSmrg const cpu_arch_option *target)
485a2dc1f3fSmrg {
486a2dc1f3fSmrg char *this_opt = XALLOCAVEC (char, len+1);
487a2dc1f3fSmrg auto_vec<const char*> candidates;
488a2dc1f3fSmrg
489a2dc1f3fSmrg strncpy (this_opt, opt, len);
490a2dc1f3fSmrg this_opt[len] = 0;
491a2dc1f3fSmrg
492a2dc1f3fSmrg error_at (input_location, "%qs does not support feature %qs", target->name,
493a2dc1f3fSmrg this_opt);
494a2dc1f3fSmrg for (const cpu_arch_extension *list = target->extensions;
495a2dc1f3fSmrg list->name != NULL;
496a2dc1f3fSmrg list++)
497a2dc1f3fSmrg candidates.safe_push (list->name);
498a2dc1f3fSmrg
499a2dc1f3fSmrg char *s;
500a2dc1f3fSmrg const char *hint = candidates_list_and_hint (this_opt, s, candidates);
501a2dc1f3fSmrg
502a2dc1f3fSmrg if (hint)
503a2dc1f3fSmrg inform (input_location, "valid feature names are: %s; did you mean %qs?",
504a2dc1f3fSmrg s, hint);
505a2dc1f3fSmrg else
506a2dc1f3fSmrg inform (input_location, "valid feature names are: %s", s);
507a2dc1f3fSmrg
508a2dc1f3fSmrg XDELETEVEC (s);
509a2dc1f3fSmrg }
510a2dc1f3fSmrg
511a2dc1f3fSmrg /* Parse any feature extensions to add to (or remove from) the
512a2dc1f3fSmrg permitted ISA selection. */
513a2dc1f3fSmrg void
arm_parse_option_features(sbitmap isa,const cpu_arch_option * target,const char * opts_in)514a2dc1f3fSmrg arm_parse_option_features (sbitmap isa, const cpu_arch_option *target,
515a2dc1f3fSmrg const char *opts_in)
516a2dc1f3fSmrg {
517a2dc1f3fSmrg const char *opts = opts_in;
518a2dc1f3fSmrg
519a2dc1f3fSmrg if (!opts)
520a2dc1f3fSmrg return;
521a2dc1f3fSmrg
522a2dc1f3fSmrg if (!target->extensions)
523a2dc1f3fSmrg {
524a2dc1f3fSmrg error_at (input_location, "%s does not take any feature options",
525a2dc1f3fSmrg target->name);
526a2dc1f3fSmrg return;
527a2dc1f3fSmrg }
528a2dc1f3fSmrg
529a2dc1f3fSmrg while (opts)
530a2dc1f3fSmrg {
531a2dc1f3fSmrg gcc_assert (*opts == '+');
532a2dc1f3fSmrg const struct cpu_arch_extension *entry;
533a2dc1f3fSmrg const char *end = strchr (++opts, '+');
534a2dc1f3fSmrg size_t len = end ? end - opts : strlen (opts);
535a2dc1f3fSmrg bool matched = false;
536a2dc1f3fSmrg
537a2dc1f3fSmrg for (entry = target->extensions;
538a2dc1f3fSmrg !matched && entry->name != NULL;
539a2dc1f3fSmrg entry++)
540a2dc1f3fSmrg {
541a2dc1f3fSmrg if (strncmp (entry->name, opts, len) == 0
542a2dc1f3fSmrg && entry->name[len] == '\0')
543a2dc1f3fSmrg {
544a2dc1f3fSmrg if (isa)
545a2dc1f3fSmrg {
546a2dc1f3fSmrg const enum isa_feature *f = entry->isa_bits;
547a2dc1f3fSmrg if (entry->remove)
548a2dc1f3fSmrg {
549a2dc1f3fSmrg while (*f != isa_nobit)
550a2dc1f3fSmrg bitmap_clear_bit (isa, *(f++));
551a2dc1f3fSmrg }
552a2dc1f3fSmrg else
553a2dc1f3fSmrg {
554a2dc1f3fSmrg while (*f != isa_nobit)
555a2dc1f3fSmrg bitmap_set_bit (isa, *(f++));
556a2dc1f3fSmrg }
557a2dc1f3fSmrg }
558a2dc1f3fSmrg matched = true;
559a2dc1f3fSmrg }
560a2dc1f3fSmrg }
561a2dc1f3fSmrg
562a2dc1f3fSmrg if (!matched)
563a2dc1f3fSmrg arm_unrecognized_feature (opts, len, target);
564a2dc1f3fSmrg
565a2dc1f3fSmrg opts = end;
566a2dc1f3fSmrg }
567a2dc1f3fSmrg }
568a2dc1f3fSmrg
569a2dc1f3fSmrg class candidate_extension
570a2dc1f3fSmrg {
571a2dc1f3fSmrg public:
572a2dc1f3fSmrg const cpu_arch_extension *extension;
573a2dc1f3fSmrg sbitmap isa_bits;
574a2dc1f3fSmrg bool required;
575a2dc1f3fSmrg
candidate_extension(const cpu_arch_extension * ext,sbitmap bits)576a2dc1f3fSmrg candidate_extension (const cpu_arch_extension *ext, sbitmap bits)
577a2dc1f3fSmrg : extension (ext), isa_bits (bits), required (true)
578a2dc1f3fSmrg {}
~candidate_extension()579a2dc1f3fSmrg ~candidate_extension ()
580a2dc1f3fSmrg {
581a2dc1f3fSmrg sbitmap_free (isa_bits);
582a2dc1f3fSmrg }
583a2dc1f3fSmrg };
584a2dc1f3fSmrg
585a2dc1f3fSmrg /* Generate a canonical representation of the -march option from the
586a2dc1f3fSmrg current -march string (if given) and other options on the command
587a2dc1f3fSmrg line that might affect the architecture. This aids multilib selection
588a2dc1f3fSmrg by ensuring that:
589a2dc1f3fSmrg a) the option is always present
590a2dc1f3fSmrg b) only the minimal set of options are used
591a2dc1f3fSmrg c) when there are multiple extensions, they are in a consistent order.
592a2dc1f3fSmrg
593a2dc1f3fSmrg The options array consists of couplets of information where the
594a2dc1f3fSmrg first item in each couplet is the string describing which option
595a2dc1f3fSmrg name was selected (arch, cpu, fpu) and the second is the value
596*8feb0f0bSmrg passed for that option.
597*8feb0f0bSmrg
598*8feb0f0bSmrg arch_for_multilib is boolean variable taking value true or false.
599*8feb0f0bSmrg arch_for_multilib is false when the canonical representation is for -march
600*8feb0f0bSmrg option and it is true when canonical representation is for -mlibarch option.
601*8feb0f0bSmrg On passing arch_for_multilib true the canonical string generated will be
602*8feb0f0bSmrg without the compiler options which are not required for multilib linking. */
603*8feb0f0bSmrg static const char *
arm_canon_arch_option_1(int argc,const char ** argv,bool arch_for_multilib)604*8feb0f0bSmrg arm_canon_arch_option_1 (int argc, const char **argv, bool arch_for_multilib)
605a2dc1f3fSmrg {
606a2dc1f3fSmrg const char *arch = NULL;
607a2dc1f3fSmrg const char *cpu = NULL;
608a2dc1f3fSmrg const char *fpu = NULL;
609a2dc1f3fSmrg const char *abi = NULL;
610a2dc1f3fSmrg static char *canonical_arch = NULL;
611a2dc1f3fSmrg
612a2dc1f3fSmrg /* Just in case we're called more than once. */
613a2dc1f3fSmrg if (canonical_arch)
614a2dc1f3fSmrg {
615a2dc1f3fSmrg free (canonical_arch);
616a2dc1f3fSmrg canonical_arch = NULL;
617a2dc1f3fSmrg }
618a2dc1f3fSmrg
619a2dc1f3fSmrg if (argc & 1)
620a2dc1f3fSmrg fatal_error (input_location,
621a2dc1f3fSmrg "%%:canon_for_mlib takes 1 or more pairs of parameters");
622a2dc1f3fSmrg
623a2dc1f3fSmrg while (argc)
624a2dc1f3fSmrg {
625a2dc1f3fSmrg if (strcmp (argv[0], "arch") == 0)
626a2dc1f3fSmrg arch = argv[1];
627a2dc1f3fSmrg else if (strcmp (argv[0], "cpu") == 0)
628a2dc1f3fSmrg cpu = argv[1];
629a2dc1f3fSmrg else if (strcmp (argv[0], "fpu") == 0)
630a2dc1f3fSmrg fpu = argv[1];
631a2dc1f3fSmrg else if (strcmp (argv[0], "abi") == 0)
632a2dc1f3fSmrg abi = argv[1];
633a2dc1f3fSmrg else
634a2dc1f3fSmrg fatal_error (input_location,
635a2dc1f3fSmrg "unrecognized operand to %%:canon_for_mlib");
636a2dc1f3fSmrg
637a2dc1f3fSmrg argc -= 2;
638a2dc1f3fSmrg argv += 2;
639a2dc1f3fSmrg }
640a2dc1f3fSmrg
641a2dc1f3fSmrg auto_sbitmap target_isa (isa_num_bits);
642a2dc1f3fSmrg auto_sbitmap base_isa (isa_num_bits);
643a2dc1f3fSmrg auto_sbitmap fpu_isa (isa_num_bits);
644a2dc1f3fSmrg
645a2dc1f3fSmrg bitmap_clear (fpu_isa);
646a2dc1f3fSmrg
647a2dc1f3fSmrg const arch_option *selected_arch = NULL;
648a2dc1f3fSmrg
649a2dc1f3fSmrg /* At least one of these must be defined by either the specs or the
650a2dc1f3fSmrg user. */
651a2dc1f3fSmrg gcc_assert (cpu || arch);
652a2dc1f3fSmrg
653a2dc1f3fSmrg if (!fpu)
654a2dc1f3fSmrg fpu = FPUTYPE_AUTO;
655a2dc1f3fSmrg
656a2dc1f3fSmrg if (!abi)
657a2dc1f3fSmrg {
658a2dc1f3fSmrg if (TARGET_DEFAULT_FLOAT_ABI == ARM_FLOAT_ABI_SOFT)
659a2dc1f3fSmrg abi = "soft";
660a2dc1f3fSmrg else if (TARGET_DEFAULT_FLOAT_ABI == ARM_FLOAT_ABI_SOFTFP)
661a2dc1f3fSmrg abi = "softfp";
662a2dc1f3fSmrg else if (TARGET_DEFAULT_FLOAT_ABI == ARM_FLOAT_ABI_HARD)
663a2dc1f3fSmrg abi = "hard";
664a2dc1f3fSmrg }
665a2dc1f3fSmrg
666a2dc1f3fSmrg /* First build up a bitmap describing the target architecture. */
667a2dc1f3fSmrg if (arch)
668a2dc1f3fSmrg {
669*8feb0f0bSmrg selected_arch = arm_parse_arch_option_name (all_architectures, "-march",
670*8feb0f0bSmrg arch, !arch_for_multilib);
671a2dc1f3fSmrg
672a2dc1f3fSmrg if (selected_arch == NULL)
673a2dc1f3fSmrg return "";
674a2dc1f3fSmrg
675a2dc1f3fSmrg arm_initialize_isa (target_isa, selected_arch->common.isa_bits);
676a2dc1f3fSmrg arm_parse_option_features (target_isa, &selected_arch->common,
677a2dc1f3fSmrg strchr (arch, '+'));
678*8feb0f0bSmrg if (arch_for_multilib)
679*8feb0f0bSmrg {
680*8feb0f0bSmrg const enum isa_feature removable_bits[] = {ISA_IGNORE_FOR_MULTILIB,
681*8feb0f0bSmrg isa_nobit};
682*8feb0f0bSmrg sbitmap isa_bits = sbitmap_alloc (isa_num_bits);
683*8feb0f0bSmrg arm_initialize_isa (isa_bits, removable_bits);
684*8feb0f0bSmrg bitmap_and_compl (target_isa, target_isa, isa_bits);
685*8feb0f0bSmrg }
686*8feb0f0bSmrg
687a2dc1f3fSmrg if (fpu && strcmp (fpu, "auto") != 0)
688a2dc1f3fSmrg {
689a2dc1f3fSmrg /* We assume that architectures do not have any FPU bits
690a2dc1f3fSmrg enabled by default. If they did, we would need to strip
691a2dc1f3fSmrg these out first. */
692a2dc1f3fSmrg const arm_fpu_desc *target_fpu = arm_parse_fpu_option (fpu);
693a2dc1f3fSmrg if (target_fpu == NULL)
694a2dc1f3fSmrg return "";
695a2dc1f3fSmrg
696a2dc1f3fSmrg arm_initialize_isa (fpu_isa, target_fpu->isa_bits);
697a2dc1f3fSmrg bitmap_ior (target_isa, target_isa, fpu_isa);
698a2dc1f3fSmrg }
699a2dc1f3fSmrg }
700a2dc1f3fSmrg else if (cpu)
701a2dc1f3fSmrg {
702a2dc1f3fSmrg const cpu_option *selected_cpu
703*8feb0f0bSmrg = arm_parse_cpu_option_name (all_cores, "-mcpu", cpu,
704*8feb0f0bSmrg !arch_for_multilib);
705a2dc1f3fSmrg
706a2dc1f3fSmrg if (selected_cpu == NULL)
707a2dc1f3fSmrg return "";
708a2dc1f3fSmrg
709a2dc1f3fSmrg arm_initialize_isa (target_isa, selected_cpu->common.isa_bits);
710a2dc1f3fSmrg arm_parse_option_features (target_isa, &selected_cpu->common,
711a2dc1f3fSmrg strchr (cpu, '+'));
712a2dc1f3fSmrg if (fpu && strcmp (fpu, "auto") != 0)
713a2dc1f3fSmrg {
714a2dc1f3fSmrg /* The easiest and safest way to remove the default fpu
715a2dc1f3fSmrg capabilities is to look for a '+no..' option that removes
716a2dc1f3fSmrg the base FPU bit (isa_bit_vfpv2). If that doesn't exist
717a2dc1f3fSmrg then the best we can do is strip out all the bits that
718a2dc1f3fSmrg might be part of the most capable FPU we know about,
719a2dc1f3fSmrg which is "crypto-neon-fp-armv8". */
720a2dc1f3fSmrg bool default_fpu_found = false;
721a2dc1f3fSmrg if (selected_cpu->common.extensions)
722a2dc1f3fSmrg {
723a2dc1f3fSmrg const cpu_arch_extension *ext;
724a2dc1f3fSmrg for (ext = selected_cpu->common.extensions; ext->name != NULL;
725a2dc1f3fSmrg ++ext)
726a2dc1f3fSmrg {
727a2dc1f3fSmrg if (ext->remove
728a2dc1f3fSmrg && check_isa_bits_for (ext->isa_bits, isa_bit_vfpv2))
729a2dc1f3fSmrg {
730a2dc1f3fSmrg arm_initialize_isa (fpu_isa, ext->isa_bits);
731a2dc1f3fSmrg bitmap_and_compl (target_isa, target_isa, fpu_isa);
732a2dc1f3fSmrg default_fpu_found = true;
733a2dc1f3fSmrg }
734a2dc1f3fSmrg }
735a2dc1f3fSmrg
736a2dc1f3fSmrg }
737a2dc1f3fSmrg
738a2dc1f3fSmrg if (!default_fpu_found)
739a2dc1f3fSmrg {
740a2dc1f3fSmrg arm_initialize_isa
741a2dc1f3fSmrg (fpu_isa,
742a2dc1f3fSmrg all_fpus[TARGET_FPU_crypto_neon_fp_armv8].isa_bits);
743a2dc1f3fSmrg bitmap_and_compl (target_isa, target_isa, fpu_isa);
744a2dc1f3fSmrg }
745a2dc1f3fSmrg
746a2dc1f3fSmrg const arm_fpu_desc *target_fpu = arm_parse_fpu_option (fpu);
747a2dc1f3fSmrg if (target_fpu == NULL)
748a2dc1f3fSmrg return "";
749a2dc1f3fSmrg
750a2dc1f3fSmrg arm_initialize_isa (fpu_isa, target_fpu->isa_bits);
751a2dc1f3fSmrg bitmap_ior (target_isa, target_isa, fpu_isa);
752a2dc1f3fSmrg }
753a2dc1f3fSmrg
754a2dc1f3fSmrg selected_arch = all_architectures + selected_cpu->arch;
755a2dc1f3fSmrg }
756a2dc1f3fSmrg
757a2dc1f3fSmrg /* If we have a soft-float ABI, disable the FPU. */
758a2dc1f3fSmrg if (abi && strcmp (abi, "soft") == 0)
759a2dc1f3fSmrg {
760a2dc1f3fSmrg /* Clearing the VFPv2 bit is sufficient to stop any extention that
761a2dc1f3fSmrg builds on the FPU from matching. */
762a2dc1f3fSmrg bitmap_clear_bit (target_isa, isa_bit_vfpv2);
763a2dc1f3fSmrg }
764a2dc1f3fSmrg
765a2dc1f3fSmrg /* If we don't have a selected architecture by now, something's
766a2dc1f3fSmrg badly wrong. */
767a2dc1f3fSmrg gcc_assert (selected_arch);
768a2dc1f3fSmrg
769a2dc1f3fSmrg arm_initialize_isa (base_isa, selected_arch->common.isa_bits);
770a2dc1f3fSmrg
771a2dc1f3fSmrg /* Architecture has no extension options, so just return the canonical
772a2dc1f3fSmrg architecture name. */
773a2dc1f3fSmrg if (selected_arch->common.extensions == NULL)
774a2dc1f3fSmrg return selected_arch->common.name;
775a2dc1f3fSmrg
776a2dc1f3fSmrg /* We're only interested in extension bits. */
777a2dc1f3fSmrg bitmap_and_compl (target_isa, target_isa, base_isa);
778a2dc1f3fSmrg
779a2dc1f3fSmrg /* There are no extensions needed. Just return the canonical architecture
780a2dc1f3fSmrg name. */
781a2dc1f3fSmrg if (bitmap_empty_p (target_isa))
782a2dc1f3fSmrg return selected_arch->common.name;
783a2dc1f3fSmrg
784a2dc1f3fSmrg /* What is left is the architecture that the compiler will target. We
785a2dc1f3fSmrg now need to map that back into a suitable option+features list.
786a2dc1f3fSmrg
787a2dc1f3fSmrg The list is built in two passes. First we scan every additive
788a2dc1f3fSmrg option feature supported by the architecture. If the option
789a2dc1f3fSmrg provides a subset of the features we need we add it to the list
790a2dc1f3fSmrg of candidates. We then scan backwards over the list of
791a2dc1f3fSmrg candidates and if we find a feature that adds nothing to one that
792a2dc1f3fSmrg was later in the list we mark it as redundant. The result is a
793a2dc1f3fSmrg minimal list of required features for the target
794a2dc1f3fSmrg architecture. */
795a2dc1f3fSmrg
796a2dc1f3fSmrg std::list<candidate_extension *> extensions;
797a2dc1f3fSmrg
798a2dc1f3fSmrg auto_sbitmap target_isa_unsatisfied (isa_num_bits);
799a2dc1f3fSmrg bitmap_copy (target_isa_unsatisfied, target_isa);
800a2dc1f3fSmrg
801a2dc1f3fSmrg sbitmap isa_bits = NULL;
802a2dc1f3fSmrg for (const cpu_arch_extension *cand = selected_arch->common.extensions;
803a2dc1f3fSmrg cand->name != NULL;
804a2dc1f3fSmrg cand++)
805a2dc1f3fSmrg {
806a2dc1f3fSmrg if (cand->remove || cand->alias)
807a2dc1f3fSmrg continue;
808a2dc1f3fSmrg
809a2dc1f3fSmrg if (isa_bits == NULL)
810a2dc1f3fSmrg isa_bits = sbitmap_alloc (isa_num_bits);
811a2dc1f3fSmrg
812a2dc1f3fSmrg arm_initialize_isa (isa_bits, cand->isa_bits);
813a2dc1f3fSmrg if (bitmap_subset_p (isa_bits, target_isa))
814a2dc1f3fSmrg {
815a2dc1f3fSmrg extensions.push_back (new candidate_extension (cand, isa_bits));
816a2dc1f3fSmrg bitmap_and_compl (target_isa_unsatisfied, target_isa_unsatisfied,
817a2dc1f3fSmrg isa_bits);
818a2dc1f3fSmrg isa_bits = NULL;
819a2dc1f3fSmrg }
820a2dc1f3fSmrg }
821a2dc1f3fSmrg
822a2dc1f3fSmrg /* There's one extra case to consider, which is that the user has
823a2dc1f3fSmrg specified an FPU that is less capable than this architecture
824a2dc1f3fSmrg supports. In that case the code above will fail to find a
825a2dc1f3fSmrg suitable feature. We handle this by scanning the list of options
826a2dc1f3fSmrg again, matching the first option that provides an FPU that is
827a2dc1f3fSmrg more capable than the selected FPU.
828a2dc1f3fSmrg
829a2dc1f3fSmrg Note that the other case (user specified a more capable FPU than
830a2dc1f3fSmrg this architecture supports) should end up selecting the most
831a2dc1f3fSmrg capable FPU variant that we do support. This is sufficient for
832a2dc1f3fSmrg multilib selection. */
833a2dc1f3fSmrg
834a2dc1f3fSmrg if (bitmap_bit_p (target_isa_unsatisfied, isa_bit_vfpv2)
835a2dc1f3fSmrg && bitmap_bit_p (fpu_isa, isa_bit_vfpv2))
836a2dc1f3fSmrg {
837a2dc1f3fSmrg std::list<candidate_extension *>::iterator ipoint = extensions.begin ();
838a2dc1f3fSmrg
839a2dc1f3fSmrg for (const cpu_arch_extension *cand = selected_arch->common.extensions;
840a2dc1f3fSmrg cand->name != NULL;
841a2dc1f3fSmrg cand++)
842a2dc1f3fSmrg {
843a2dc1f3fSmrg if (cand->remove || cand->alias)
844a2dc1f3fSmrg continue;
845a2dc1f3fSmrg
846a2dc1f3fSmrg if (isa_bits == NULL)
847a2dc1f3fSmrg isa_bits = sbitmap_alloc (isa_num_bits);
848a2dc1f3fSmrg
849a2dc1f3fSmrg /* We need to keep the features in canonical order, so move the
850a2dc1f3fSmrg insertion point if this feature is a candidate. */
851a2dc1f3fSmrg if (ipoint != extensions.end ()
852a2dc1f3fSmrg && (*ipoint)->extension == cand)
853a2dc1f3fSmrg ++ipoint;
854a2dc1f3fSmrg
855a2dc1f3fSmrg arm_initialize_isa (isa_bits, cand->isa_bits);
856a2dc1f3fSmrg if (bitmap_subset_p (fpu_isa, isa_bits))
857a2dc1f3fSmrg {
858a2dc1f3fSmrg extensions.insert (ipoint,
859a2dc1f3fSmrg new candidate_extension (cand, isa_bits));
860a2dc1f3fSmrg isa_bits = NULL;
861a2dc1f3fSmrg break;
862a2dc1f3fSmrg }
863a2dc1f3fSmrg }
864a2dc1f3fSmrg }
865a2dc1f3fSmrg
866a2dc1f3fSmrg if (isa_bits)
867a2dc1f3fSmrg sbitmap_free (isa_bits);
868a2dc1f3fSmrg
869a2dc1f3fSmrg bitmap_clear (target_isa);
870a2dc1f3fSmrg size_t len = 1;
871a2dc1f3fSmrg for (std::list<candidate_extension *>::reverse_iterator riter
872a2dc1f3fSmrg = extensions.rbegin ();
873a2dc1f3fSmrg riter != extensions.rend (); ++riter)
874a2dc1f3fSmrg {
875a2dc1f3fSmrg if (bitmap_subset_p ((*riter)->isa_bits, target_isa))
876a2dc1f3fSmrg (*riter)->required = false;
877a2dc1f3fSmrg else
878a2dc1f3fSmrg {
879a2dc1f3fSmrg bitmap_ior (target_isa, target_isa, (*riter)->isa_bits);
880a2dc1f3fSmrg len += strlen ((*riter)->extension->name) + 1;
881a2dc1f3fSmrg }
882a2dc1f3fSmrg }
883a2dc1f3fSmrg
884a2dc1f3fSmrg canonical_arch
885a2dc1f3fSmrg = (char *) xmalloc (len + strlen (selected_arch->common.name));
886a2dc1f3fSmrg
887a2dc1f3fSmrg strcpy (canonical_arch, selected_arch->common.name);
888a2dc1f3fSmrg
889a2dc1f3fSmrg for (std::list<candidate_extension *>::iterator iter = extensions.begin ();
890a2dc1f3fSmrg iter != extensions.end (); ++iter)
891a2dc1f3fSmrg {
892a2dc1f3fSmrg if ((*iter)->required)
893a2dc1f3fSmrg {
894a2dc1f3fSmrg strcat (canonical_arch, "+");
895a2dc1f3fSmrg strcat (canonical_arch, (*iter)->extension->name);
896a2dc1f3fSmrg }
897a2dc1f3fSmrg delete (*iter);
898a2dc1f3fSmrg }
899a2dc1f3fSmrg
900a2dc1f3fSmrg return canonical_arch;
901a2dc1f3fSmrg }
902a2dc1f3fSmrg
903a2dc1f3fSmrg /* If building big-endian on a BE8 target generate a --be8 option for
904a2dc1f3fSmrg the linker. Takes four types of option: "little" - little-endian;
905a2dc1f3fSmrg "big" - big-endian; "be8" - force be8 iff big-endian; and "arch"
906a2dc1f3fSmrg "<arch-name>" (two arguments) - the target architecture. The
907a2dc1f3fSmrg parameter names are generated by the driver from the command-line
908a2dc1f3fSmrg options. */
909a2dc1f3fSmrg const char *
arm_be8_option(int argc,const char ** argv)910a2dc1f3fSmrg arm_be8_option (int argc, const char **argv)
911a2dc1f3fSmrg {
912a2dc1f3fSmrg int endian = TARGET_ENDIAN_DEFAULT;
913a2dc1f3fSmrg const char *arch = NULL;
914a2dc1f3fSmrg int arg;
915a2dc1f3fSmrg bool force = false;
916a2dc1f3fSmrg
917a2dc1f3fSmrg for (arg = 0; arg < argc; arg++)
918a2dc1f3fSmrg {
919a2dc1f3fSmrg if (strcmp (argv[arg], "little") == 0)
920a2dc1f3fSmrg endian = 0;
921a2dc1f3fSmrg else if (strcmp (argv[arg], "big") == 0)
922a2dc1f3fSmrg endian = 1;
923a2dc1f3fSmrg else if (strcmp (argv[arg], "be8") == 0)
924a2dc1f3fSmrg force = true;
925a2dc1f3fSmrg else if (strcmp (argv[arg], "arch") == 0)
926a2dc1f3fSmrg {
927a2dc1f3fSmrg arg++;
928a2dc1f3fSmrg gcc_assert (arg < argc);
929a2dc1f3fSmrg arch = argv[arg];
930a2dc1f3fSmrg }
931a2dc1f3fSmrg else
932a2dc1f3fSmrg gcc_unreachable ();
933a2dc1f3fSmrg }
934a2dc1f3fSmrg
935a2dc1f3fSmrg /* Little endian - no be8 option. */
936a2dc1f3fSmrg if (!endian)
937a2dc1f3fSmrg return "";
938a2dc1f3fSmrg
939a2dc1f3fSmrg if (force)
940a2dc1f3fSmrg return "--be8";
941a2dc1f3fSmrg
942a2dc1f3fSmrg /* Arch might not be set iff arm_canon_arch (above) detected an
943a2dc1f3fSmrg error. Do nothing in that case. */
944a2dc1f3fSmrg if (!arch)
945a2dc1f3fSmrg return "";
946a2dc1f3fSmrg
947a2dc1f3fSmrg const arch_option *selected_arch
948a2dc1f3fSmrg = arm_parse_arch_option_name (all_architectures, "-march", arch);
949a2dc1f3fSmrg
950a2dc1f3fSmrg /* Similarly if the given arch option was itself invalid. */
951a2dc1f3fSmrg if (!selected_arch)
952a2dc1f3fSmrg return "";
953a2dc1f3fSmrg
954a2dc1f3fSmrg if (check_isa_bits_for (selected_arch->common.isa_bits, isa_bit_be8))
955a2dc1f3fSmrg return "--be8";
956a2dc1f3fSmrg
957a2dc1f3fSmrg return "";
958a2dc1f3fSmrg }
959a2dc1f3fSmrg
960a2dc1f3fSmrg /* Generate a -mfpu= option for passing to the assembler. This is
961a2dc1f3fSmrg only called when -mfpu was set (possibly defaulted) to auto and is
962a2dc1f3fSmrg needed to ensure that the assembler knows the correct FPU to use.
963a2dc1f3fSmrg It wouldn't really be needed except that the compiler can be used
964a2dc1f3fSmrg to invoke the assembler directly on hand-written files that lack
965a2dc1f3fSmrg the necessary internal .fpu directives. We assume that the architecture
966a2dc1f3fSmrg canonicalization calls have already been made so that we have a final
967a2dc1f3fSmrg -march= option to derive the fpu from. */
968a2dc1f3fSmrg const char*
arm_asm_auto_mfpu(int argc,const char ** argv)969a2dc1f3fSmrg arm_asm_auto_mfpu (int argc, const char **argv)
970a2dc1f3fSmrg {
971a2dc1f3fSmrg static char *auto_fpu = NULL;
972a2dc1f3fSmrg const char *arch = NULL;
973a2dc1f3fSmrg static const enum isa_feature fpu_bitlist[]
974a2dc1f3fSmrg = { ISA_ALL_FPU_INTERNAL, isa_nobit };
975a2dc1f3fSmrg const arch_option *selected_arch;
976a2dc1f3fSmrg static const char* fpuname = "softvfp";
977a2dc1f3fSmrg
978a2dc1f3fSmrg /* Handle multiple calls to this routine. */
979a2dc1f3fSmrg if (auto_fpu)
980a2dc1f3fSmrg {
981a2dc1f3fSmrg free (auto_fpu);
982a2dc1f3fSmrg auto_fpu = NULL;
983a2dc1f3fSmrg }
984a2dc1f3fSmrg
985a2dc1f3fSmrg while (argc)
986a2dc1f3fSmrg {
987a2dc1f3fSmrg if (strcmp (argv[0], "arch") == 0)
988a2dc1f3fSmrg arch = argv[1];
989a2dc1f3fSmrg else
990a2dc1f3fSmrg fatal_error (input_location,
991a2dc1f3fSmrg "unrecognized operand to %%:asm_auto_mfpu");
992a2dc1f3fSmrg argc -= 2;
993a2dc1f3fSmrg argv += 2;
994a2dc1f3fSmrg }
995a2dc1f3fSmrg
996a2dc1f3fSmrg auto_sbitmap target_isa (isa_num_bits);
997a2dc1f3fSmrg auto_sbitmap fpubits (isa_num_bits);
998a2dc1f3fSmrg
999a2dc1f3fSmrg gcc_assert (arch != NULL);
1000a2dc1f3fSmrg selected_arch = arm_parse_arch_option_name (all_architectures,
1001a2dc1f3fSmrg "-march", arch);
1002a2dc1f3fSmrg if (selected_arch == NULL)
1003a2dc1f3fSmrg return "";
1004a2dc1f3fSmrg
1005a2dc1f3fSmrg arm_initialize_isa (target_isa, selected_arch->common.isa_bits);
1006a2dc1f3fSmrg arm_parse_option_features (target_isa, &selected_arch->common,
1007a2dc1f3fSmrg strchr (arch, '+'));
1008a2dc1f3fSmrg arm_initialize_isa (fpubits, fpu_bitlist);
1009a2dc1f3fSmrg
1010a2dc1f3fSmrg bitmap_and (fpubits, fpubits, target_isa);
1011a2dc1f3fSmrg
1012a2dc1f3fSmrg /* The logic below is essentially identical to that in
1013a2dc1f3fSmrg arm.c:arm_identify_fpu_from_isa(), but that only works in the main
1014a2dc1f3fSmrg part of the compiler. */
1015a2dc1f3fSmrg
1016a2dc1f3fSmrg /* If there are no FPU capability bits, we just pass -mfpu=softvfp. */
1017a2dc1f3fSmrg if (!bitmap_empty_p (fpubits))
1018a2dc1f3fSmrg {
1019a2dc1f3fSmrg unsigned int i;
1020a2dc1f3fSmrg auto_sbitmap cand_fpubits (isa_num_bits);
1021a2dc1f3fSmrg for (i = 0; i < TARGET_FPU_auto; i++)
1022a2dc1f3fSmrg {
1023a2dc1f3fSmrg arm_initialize_isa (cand_fpubits, all_fpus[i].isa_bits);
1024a2dc1f3fSmrg if (bitmap_equal_p (fpubits, cand_fpubits))
1025a2dc1f3fSmrg {
1026a2dc1f3fSmrg fpuname = all_fpus[i].name;
1027a2dc1f3fSmrg break;
1028a2dc1f3fSmrg }
1029a2dc1f3fSmrg }
1030a2dc1f3fSmrg
1031*8feb0f0bSmrg gcc_assert (i != TARGET_FPU_auto
1032*8feb0f0bSmrg || bitmap_bit_p (target_isa, isa_bit_vfp_base));
1033a2dc1f3fSmrg }
1034a2dc1f3fSmrg
1035a2dc1f3fSmrg auto_fpu = (char *) xmalloc (strlen (fpuname) + sizeof ("-mfpu="));
1036a2dc1f3fSmrg strcpy (auto_fpu, "-mfpu=");
1037a2dc1f3fSmrg strcat (auto_fpu, fpuname);
1038a2dc1f3fSmrg return auto_fpu;
1039a2dc1f3fSmrg }
1040a2dc1f3fSmrg
104136ac495dSmrg #undef ARM_CPU_NAME_LENGTH
104236ac495dSmrg
104336ac495dSmrg
104436ac495dSmrg #undef TARGET_DEFAULT_TARGET_FLAGS
104536ac495dSmrg #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_SCHED_PROLOG)
104636ac495dSmrg
104736ac495dSmrg #undef TARGET_OPTION_OPTIMIZATION_TABLE
104836ac495dSmrg #define TARGET_OPTION_OPTIMIZATION_TABLE arm_option_optimization_table
104936ac495dSmrg
105036ac495dSmrg #undef TARGET_EXCEPT_UNWIND_INFO
105136ac495dSmrg #define TARGET_EXCEPT_UNWIND_INFO arm_except_unwind_info
105236ac495dSmrg
105336ac495dSmrg struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
1054*8feb0f0bSmrg
1055*8feb0f0bSmrg /* Returns a canonical representation of the -march option from the current
1056*8feb0f0bSmrg -march string (if given) and other options on the command line that might
1057*8feb0f0bSmrg affect the architecture. */
1058*8feb0f0bSmrg const char *
arm_canon_arch_option(int argc,const char ** argv)1059*8feb0f0bSmrg arm_canon_arch_option (int argc, const char **argv)
1060*8feb0f0bSmrg {
1061*8feb0f0bSmrg return arm_canon_arch_option_1 (argc, argv, false);
1062*8feb0f0bSmrg }
1063*8feb0f0bSmrg
1064*8feb0f0bSmrg /* Returns a canonical representation of the -mlibarch option from the current
1065*8feb0f0bSmrg -march string (if given) and other options on the command line that might
1066*8feb0f0bSmrg affect the architecture after removing the compiler extension options which
1067*8feb0f0bSmrg are not required for multilib linking. */
1068*8feb0f0bSmrg const char *
arm_canon_arch_multilib_option(int argc,const char ** argv)1069*8feb0f0bSmrg arm_canon_arch_multilib_option (int argc, const char **argv)
1070*8feb0f0bSmrg {
1071*8feb0f0bSmrg return arm_canon_arch_option_1 (argc, argv, true);
1072*8feb0f0bSmrg }
1073