xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/common/config/arm/arm-common.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
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