/* Common hooks for ARM.
   Copyright (C) 1991-2018 Free Software Foundation, Inc.

   This file is part of GCC.

   GCC is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published
   by the Free Software Foundation; either version 3, or (at your
   option) any later version.

   GCC is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   License for more details.

   You should have received a copy of the GNU General Public License
   along with GCC; see the file COPYING3.  If not see
   <http://www.gnu.org/licenses/>.  */

#define INCLUDE_LIST
#define INCLUDE_VECTOR
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "memmodel.h"
#include "tm_p.h"
#include "common/common-target.h"
#include "common/common-target-def.h"
#include "opts.h"
#include "flags.h"
#include "sbitmap.h"
#include "diagnostic.h"
#include <algorithm>

/* Set default optimization options.  */
static const struct default_options arm_option_optimization_table[] =
  {
    /* Enable section anchors by default at -O1 or higher.  */
    { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
    { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 },
    { OPT_LEVELS_NONE, 0, NULL, 0 }
  };

/* Implement TARGET_EXCEPT_UNWIND_INFO.  */

enum unwind_info_type
arm_except_unwind_info (struct gcc_options *opts)
{
  /* Honor the --enable-sjlj-exceptions configure switch.  */
#ifdef CONFIG_SJLJ_EXCEPTIONS
  if (CONFIG_SJLJ_EXCEPTIONS)
    return UI_SJLJ;
#endif

  /* If not using ARM EABI unwind tables... */
  if (ARM_UNWIND_INFO)
    {
      /* For simplicity elsewhere in this file, indicate that all unwind
	 info is disabled if we're not emitting unwind tables.  */
      if (!opts->x_flag_exceptions && !opts->x_flag_unwind_tables)
	return UI_NONE;
      else
	return UI_TARGET;
    }

  /* ... honor target configurations requesting DWARF2 EH...  */
#ifdef DWARF2_UNWIND_INFO
  if (DWARF2_UNWIND_INFO)
    return UI_DWARF2;
#endif

  /* ... or fallback to sjlj exceptions for backwards compatibility.  */
  return UI_SJLJ;
}

#define ARM_CPU_NAME_LENGTH 20

/* Truncate NAME at the first '.' or '+' character seen, or return
   NAME unmodified.  */

const char *
arm_rewrite_selected_cpu (const char *name)
{
  static char output_buf[ARM_CPU_NAME_LENGTH + 1] = {0};
  char *arg_pos;

  strncpy (output_buf, name, ARM_CPU_NAME_LENGTH);
  output_buf[ARM_CPU_NAME_LENGTH] = 0;

  arg_pos = strchr (output_buf, '.');

  /* If we found a '.' truncate the entry at that point.  */
  if (arg_pos)
    *arg_pos = '\0';

  arg_pos = strchr (output_buf, '+');

  /* If we found a '+' truncate the entry at that point.  */
  if (arg_pos)
    *arg_pos = '\0';

  return output_buf;
}

/* Called by the driver to rewrite a name passed to the -mcpu
   argument in preparation to be passed to the assembler.  The
   names passed from the command line will be in ARGV, we want
   to use the right-most argument, which should be in
   ARGV[ARGC - 1].  ARGC should always be greater than 0.  */

const char *
arm_rewrite_mcpu (int argc, const char **argv)
{
  gcc_assert (argc);
  return arm_rewrite_selected_cpu (argv[argc - 1]);
}

/* Comparator for arm_rewrite_selected_arch.  Compare the two arch extension
   strings FIRST and SECOND and return TRUE if FIRST is less than SECOND
   alphabetically.  */

static bool
compare_opt_names (const char *first, const char *second)
{
  return strcmp (first, second) <= 0;
}

/* Rewrite the architecture string for passing to the assembler.
   Although the syntax is similar we cannot assume that it supports
   the newer FP related options.  So strip any option that only
   defines features in the standard -mfpu options out.  We'll generate
   a suitable -mfpu option elsewhere to carry that information.  NAME
   should already have been canonicalized, so we do not expect to
   encounter +no.. options that remove features.  A final problem is
   that the assembler expects the feature extensions to be listed
   alphabetically, so we build a list of required options and then
   sort them into canonical order in the resulting string.  */
const char *
arm_rewrite_selected_arch (const char *name)
{
  /* The result we return needs to be semi persistent, so handle being
     re-invoked.  */
  static char *asm_arch = NULL;

  if (asm_arch)
    {
      free (asm_arch);
      asm_arch = NULL;
    }

  const char *arg_pos = strchr (name, '+');

  /* No extension options? just return the original string.  */
  if (arg_pos == NULL)
    return name;

  const arch_option *arch_opt
    = arm_parse_arch_option_name (all_architectures, "-march", name);

  auto_sbitmap fpu_bits (isa_num_bits);
  static const enum isa_feature fpu_bitlist[]
    = { ISA_ALL_FPU_INTERNAL, isa_nobit };

  arm_initialize_isa (fpu_bits, fpu_bitlist);

  auto_sbitmap opt_bits (isa_num_bits);

  /* Ensure that the resulting string is large enough for the result.  We
     never add options, so using strdup here will ensure that.  */
  asm_arch = xstrdup (name);
  asm_arch[arg_pos - name] = '\0';

  std::vector<const char *>optlist;

  while (arg_pos)
    {
      const char *end = strchr (arg_pos + 1, '+');
      size_t len = end ? end - arg_pos : strlen (arg_pos);

      for (const cpu_arch_extension *entry = arch_opt->common.extensions;
	   entry->name != NULL;
	   entry++)
	{
	  if (strncmp (entry->name, arg_pos + 1, len - 1) == 0
	      && entry->name[len - 1] == '\0')
	    {
	      /* Don't expect removal options.  */
	      gcc_assert (!entry->remove);
	      arm_initialize_isa (opt_bits, entry->isa_bits);
	      if (!bitmap_subset_p (opt_bits, fpu_bits))
		optlist.push_back (entry->name);
	      bitmap_clear (opt_bits);
	      break;
	    }
	}

      arg_pos = end;
    }

  std::sort (optlist.begin (), optlist.end (), compare_opt_names);

  for (std::vector<const char *>::iterator opt_iter = optlist.begin ();
       opt_iter != optlist.end ();
       ++opt_iter)
    {
      strcat (asm_arch, "+");
      strcat (asm_arch, (*opt_iter));
    }

  return asm_arch;
}

/* Called by the driver to rewrite a name passed to the -march
   argument in preparation to be passed to the assembler.  The
   names passed from the command line will be in ARGV, we want
   to use the right-most argument, which should be in
   ARGV[ARGC - 1].  ARGC should always be greater than 0.  */

const char *
arm_rewrite_march (int argc, const char **argv)
{
  gcc_assert (argc);
  return arm_rewrite_selected_arch (argv[argc - 1]);
}

#include "arm-cpu-cdata.h"

/* Scan over a raw feature array BITS checking for BIT being present.
   This is slower than the normal bitmask checks, but we would spend longer
   initializing that than doing the check this way.  Returns true iff
   BIT is found.  */
static bool
check_isa_bits_for (const enum isa_feature* bits, enum isa_feature bit)
{
  while (*bits != isa_nobit)
    if (*bits++ == bit)
      return true;

  return false;
}

/* Called by the driver to check whether the target denoted by current
   command line options is a Thumb-only target.  ARGV is an array of
   tupples (normally only one) where the first element of the tupple
   is 'cpu' or 'arch' and the second is the option passed to the
   compiler for that.  An architecture tupple is always taken in
   preference to a cpu tupple and the last of each type always
   overrides any earlier setting.  */

const char *
arm_target_thumb_only (int argc, const char **argv)
{
  const char *arch = NULL;
  const char *cpu = NULL;

  if (argc % 2 != 0)
    fatal_error (input_location,
		 "%%:target_mode_check takes an even number of parameters");

  while (argc)
    {
      if (strcmp (argv[0], "arch") == 0)
	arch = argv[1];
      else if (strcmp (argv[0], "cpu") == 0)
	cpu = argv[1];
      else
	fatal_error (input_location,
		     "unrecognized option passed to %%:target_mode_check");
      argc -= 2;
      argv += 2;
    }

  /* No architecture, or CPU, has option extensions that change
     whether or not we have a Thumb-only device, so there is no need
     to scan any option extensions specified.  */

  /* If the architecture is specified, that overrides any CPU setting.  */
  if (arch)
    {
      const arch_option *arch_opt
	= arm_parse_arch_option_name (all_architectures, "-march", arch,
				      false);

      if (arch_opt && !check_isa_bits_for (arch_opt->common.isa_bits,
					   isa_bit_notm))
	return "-mthumb";
    }
  else if (cpu)
    {
      const cpu_option *cpu_opt
	= arm_parse_cpu_option_name (all_cores, "-mcpu", cpu, false);

      if (cpu_opt && !check_isa_bits_for (cpu_opt->common.isa_bits,
					  isa_bit_notm))
	return "-mthumb";
    }

  /* Compiler hasn't been configured with a default, and the CPU
     doesn't require Thumb, so default to ARM.  */
  return "-marm";
}

/* List the permitted CPU option names.  If TARGET is a near miss for an
   entry, print out the suggested alternative.  */
static void
arm_print_hint_for_cpu_option (const char *target,
			       const cpu_option *list)
{
  auto_vec<const char*> candidates;
  for (; list->common.name != NULL; list++)
    {
      candidates.safe_push (list->common.name);
      if (list->aliases)
	{
	  for (const cpu_alias *alias = list->aliases; alias->name != NULL;
	       alias++)
	    if (alias->visible)
	      candidates.safe_push (alias->name);
	}
    }

#ifdef HAVE_LOCAL_CPU_DETECT
  /* Add also "native" as possible value.  */
  candidates.safe_push ("native");
#endif

  char *s;
  const char *hint = candidates_list_and_hint (target, s, candidates);
  if (hint)
    inform (input_location, "valid arguments are: %s; did you mean %qs?",
	    s, hint);
  else
    inform (input_location, "valid arguments are: %s", s);

  XDELETEVEC (s);
}

/* Parse the base component of a CPU selection in LIST.  Return a
   pointer to the entry in the architecture table.  OPTNAME is the
   name of the option we are parsing and can be used if a diagnostic
   is needed.  If COMPLAIN is true (the default) emit error
   messages and hints on invalid input.  */
const cpu_option *
arm_parse_cpu_option_name (const cpu_option *list, const char *optname,
			   const char *target, bool complain)
{
  const cpu_option *entry;
  const char *end  = strchr (target, '+');
  size_t len = end ? end - target : strlen (target);

  for (entry = list; entry->common.name != NULL; entry++)
    {
      if (strncmp (entry->common.name, target, len) == 0
	  && entry->common.name[len] == '\0')
	return entry;

      /* Match against any legal alias for this CPU candidate.  */
      if (entry->aliases)
	{
	  for (const cpu_alias *alias = entry->aliases; alias->name != NULL;
	       alias++)
	    if (strncmp (alias->name, target, len) == 0
		&& alias->name[len] == '\0')
	      return entry;
	}
    }

  if (complain)
    {
      error_at (input_location, "unrecognized %s target: %s", optname, target);
      arm_print_hint_for_cpu_option (target, list);
    }
  return NULL;
}

/* List the permitted architecture option names.  If TARGET is a near
   miss for an entry, print out the suggested alternative.  */
static void
arm_print_hint_for_arch_option (const char *target,
			       const arch_option *list)
{
  auto_vec<const char*> candidates;
  for (; list->common.name != NULL; list++)
    candidates.safe_push (list->common.name);

#ifdef HAVE_LOCAL_CPU_DETECT
  /* Add also "native" as possible value.  */
  candidates.safe_push ("native");
#endif

  char *s;
  const char *hint = candidates_list_and_hint (target, s, candidates);
  if (hint)
    inform (input_location, "valid arguments are: %s; did you mean %qs?",
	    s, hint);
  else
    inform (input_location, "valid arguments are: %s", s);

  XDELETEVEC (s);
}

/* Parse the base component of a CPU or architecture selection in
   LIST.  Return a pointer to the entry in the architecture table.
   OPTNAME is the name of the option we are parsing and can be used if
   a diagnostic is needed.  If COMPLAIN is true (the default) emit error
   messages and hints on invalid input.  */
const arch_option *
arm_parse_arch_option_name (const arch_option *list, const char *optname,
			    const char *target, bool complain)
{
  const arch_option *entry;
  const char *end  = strchr (target, '+');
  size_t len = end ? end - target : strlen (target);

  for (entry = list; entry->common.name != NULL; entry++)
    {
      if (strncmp (entry->common.name, target, len) == 0
	  && entry->common.name[len] == '\0')
	return entry;
    }

  if (complain)
    {
      error_at (input_location, "unrecognized %s target: %s", optname, target);
      arm_print_hint_for_arch_option (target, list);
    }
  return NULL;
}

/* List the permitted architecture option names.  If TARGET is a near
   miss for an entry, print out the suggested alternative.  */
static void
arm_print_hint_for_fpu_option (const char *target)
{
  auto_vec<const char*> candidates;
  for (int i = 0; i < TARGET_FPU_auto; i++)
    candidates.safe_push (all_fpus[i].name);
  char *s;
  const char *hint = candidates_list_and_hint (target, s, candidates);
  if (hint)
    inform (input_location, "valid arguments are: %s; did you mean %qs?",
	    s, hint);
  else
    inform (input_location, "valid arguments are: %s", s);

  XDELETEVEC (s);
}

static const arm_fpu_desc *
arm_parse_fpu_option (const char *opt)
{
  int i;

  for (i = 0; i < TARGET_FPU_auto; i++)
    {
      if (strcmp (all_fpus[i].name, opt) == 0)
	return all_fpus + i;
    }

  error_at (input_location, "unrecognized -mfpu target: %s", opt);
  arm_print_hint_for_fpu_option (opt);
  return NULL;
}

/* Convert a static initializer array of feature bits to sbitmap
   representation.  */
void
arm_initialize_isa (sbitmap isa, const enum isa_feature *isa_bits)
{
  bitmap_clear (isa);
  while (*isa_bits != isa_nobit)
    bitmap_set_bit (isa, *(isa_bits++));
}

/* OPT isn't a recognized feature.  Print a suitable error message and
   suggest a possible value.  Always print the list of permitted
   values.  */
static void
arm_unrecognized_feature (const char *opt, size_t len,
			  const cpu_arch_option *target)
{
  char *this_opt = XALLOCAVEC (char, len+1);
  auto_vec<const char*> candidates;

  strncpy (this_opt, opt, len);
  this_opt[len] = 0;

  error_at (input_location, "%qs does not support feature %qs", target->name,
	    this_opt);
  for (const cpu_arch_extension *list = target->extensions;
       list->name != NULL;
       list++)
    candidates.safe_push (list->name);

  char *s;
  const char *hint = candidates_list_and_hint (this_opt, s, candidates);

  if (hint)
    inform (input_location, "valid feature names are: %s; did you mean %qs?",
	    s, hint);
  else
    inform (input_location, "valid feature names are: %s", s);

  XDELETEVEC (s);
}

/* Parse any feature extensions to add to (or remove from) the
   permitted ISA selection.  */
void
arm_parse_option_features (sbitmap isa, const cpu_arch_option *target,
			   const char *opts_in)
{
  const char *opts = opts_in;

  if (!opts)
    return;

  if (!target->extensions)
    {
      error_at (input_location, "%s does not take any feature options",
		target->name);
      return;
    }

  while (opts)
    {
      gcc_assert (*opts == '+');
      const struct cpu_arch_extension *entry;
      const char *end = strchr (++opts, '+');
      size_t len = end ? end - opts : strlen (opts);
      bool matched = false;

      for (entry = target->extensions;
	   !matched && entry->name != NULL;
	   entry++)
	{
	  if (strncmp (entry->name, opts, len) == 0
	      && entry->name[len] == '\0')
	    {
	      if (isa)
		{
		  const enum isa_feature *f = entry->isa_bits;
		  if (entry->remove)
		    {
		      while (*f != isa_nobit)
			bitmap_clear_bit (isa, *(f++));
		    }
		  else
		    {
		      while (*f != isa_nobit)
			bitmap_set_bit (isa, *(f++));
		    }
		}
	      matched = true;
	    }
	}

      if (!matched)
	arm_unrecognized_feature (opts, len, target);

      opts = end;
    }
}

class candidate_extension
{
public:
  const cpu_arch_extension *extension;
  sbitmap isa_bits;
  bool required;

  candidate_extension (const cpu_arch_extension *ext, sbitmap bits)
    : extension (ext), isa_bits (bits), required (true)
    {}
  ~candidate_extension ()
    {
      sbitmap_free (isa_bits);
    }
};

/* Generate a canonical representation of the -march option from the
   current -march string (if given) and other options on the command
   line that might affect the architecture.  This aids multilib selection
   by ensuring that:
   a) the option is always present
   b) only the minimal set of options are used
   c) when there are multiple extensions, they are in a consistent order.

   The options array consists of couplets of information where the
   first item in each couplet is the string describing which option
   name was selected (arch, cpu, fpu) and the second is the value
   passed for that option.  */
const char *
arm_canon_arch_option (int argc, const char **argv)
{
  const char *arch = NULL;
  const char *cpu = NULL;
  const char *fpu = NULL;
  const char *abi = NULL;
  static char *canonical_arch = NULL;

  /* Just in case we're called more than once.  */
  if (canonical_arch)
    {
      free (canonical_arch);
      canonical_arch = NULL;
    }

  if (argc & 1)
    fatal_error (input_location,
		 "%%:canon_for_mlib takes 1 or more pairs of parameters");

  while (argc)
    {
      if (strcmp (argv[0], "arch") == 0)
	arch = argv[1];
      else if (strcmp (argv[0], "cpu") == 0)
	cpu = argv[1];
      else if (strcmp (argv[0], "fpu") == 0)
	fpu = argv[1];
      else if (strcmp (argv[0], "abi") == 0)
	abi = argv[1];
      else
	fatal_error (input_location,
		     "unrecognized operand to %%:canon_for_mlib");

      argc -= 2;
      argv += 2;
    }

  auto_sbitmap target_isa (isa_num_bits);
  auto_sbitmap base_isa (isa_num_bits);
  auto_sbitmap fpu_isa (isa_num_bits);

  bitmap_clear (fpu_isa);

  const arch_option *selected_arch = NULL;

  /* At least one of these must be defined by either the specs or the
     user.  */
  gcc_assert (cpu || arch);

  if (!fpu)
    fpu = FPUTYPE_AUTO;

  if (!abi)
    {
      if (TARGET_DEFAULT_FLOAT_ABI == ARM_FLOAT_ABI_SOFT)
	abi = "soft";
      else if (TARGET_DEFAULT_FLOAT_ABI == ARM_FLOAT_ABI_SOFTFP)
	abi = "softfp";
      else if (TARGET_DEFAULT_FLOAT_ABI == ARM_FLOAT_ABI_HARD)
	abi = "hard";
    }

  /* First build up a bitmap describing the target architecture.  */
  if (arch)
    {
      selected_arch = arm_parse_arch_option_name (all_architectures,
						  "-march", arch);

      if (selected_arch == NULL)
	return "";

      arm_initialize_isa (target_isa, selected_arch->common.isa_bits);
      arm_parse_option_features (target_isa, &selected_arch->common,
				 strchr (arch, '+'));
      if (fpu && strcmp (fpu, "auto") != 0)
	{
	  /* We assume that architectures do not have any FPU bits
	     enabled by default.  If they did, we would need to strip
	     these out first.  */
	  const arm_fpu_desc *target_fpu = arm_parse_fpu_option (fpu);
	  if (target_fpu == NULL)
	    return "";

	  arm_initialize_isa (fpu_isa, target_fpu->isa_bits);
	  bitmap_ior (target_isa, target_isa, fpu_isa);
	}
    }
  else if (cpu)
    {
      const cpu_option *selected_cpu
	= arm_parse_cpu_option_name (all_cores, "-mcpu", cpu);

      if (selected_cpu == NULL)
	return "";

      arm_initialize_isa (target_isa, selected_cpu->common.isa_bits);
      arm_parse_option_features (target_isa, &selected_cpu->common,
				 strchr (cpu, '+'));
      if (fpu && strcmp (fpu, "auto") != 0)
	{
	  /* The easiest and safest way to remove the default fpu
	     capabilities is to look for a '+no..' option that removes
	     the base FPU bit (isa_bit_vfpv2).  If that doesn't exist
	     then the best we can do is strip out all the bits that
	     might be part of the most capable FPU we know about,
	     which is "crypto-neon-fp-armv8".  */
	  bool default_fpu_found = false;
	  if (selected_cpu->common.extensions)
	    {
	      const cpu_arch_extension *ext;
	      for (ext = selected_cpu->common.extensions; ext->name != NULL;
		   ++ext)
		{
		  if (ext->remove
		      && check_isa_bits_for (ext->isa_bits, isa_bit_vfpv2))
		    {
		      arm_initialize_isa (fpu_isa, ext->isa_bits);
		      bitmap_and_compl (target_isa, target_isa, fpu_isa);
		      default_fpu_found = true;
		    }
		}

	    }

	  if (!default_fpu_found)
	    {
	      arm_initialize_isa
		(fpu_isa,
		 all_fpus[TARGET_FPU_crypto_neon_fp_armv8].isa_bits);
	      bitmap_and_compl (target_isa, target_isa, fpu_isa);
	    }

	  const arm_fpu_desc *target_fpu = arm_parse_fpu_option (fpu);
	  if (target_fpu == NULL)
	    return "";

	  arm_initialize_isa (fpu_isa, target_fpu->isa_bits);
	  bitmap_ior (target_isa, target_isa, fpu_isa);
	}

      selected_arch = all_architectures + selected_cpu->arch;
    }

  /* If we have a soft-float ABI, disable the FPU.  */
  if (abi && strcmp (abi, "soft") == 0)
    {
      /* Clearing the VFPv2 bit is sufficient to stop any extention that
	 builds on the FPU from matching.  */
      bitmap_clear_bit (target_isa, isa_bit_vfpv2);
    }

  /* If we don't have a selected architecture by now, something's
     badly wrong.  */
  gcc_assert (selected_arch);

  arm_initialize_isa (base_isa, selected_arch->common.isa_bits);

  /* Architecture has no extension options, so just return the canonical
     architecture name.  */
  if (selected_arch->common.extensions == NULL)
    return selected_arch->common.name;

  /* We're only interested in extension bits.  */
  bitmap_and_compl (target_isa, target_isa, base_isa);

  /* There are no extensions needed.  Just return the canonical architecture
     name.  */
  if (bitmap_empty_p (target_isa))
    return selected_arch->common.name;

  /* What is left is the architecture that the compiler will target.  We
     now need to map that back into a suitable option+features list.

     The list is built in two passes.  First we scan every additive
     option feature supported by the architecture.  If the option
     provides a subset of the features we need we add it to the list
     of candidates.  We then scan backwards over the list of
     candidates and if we find a feature that adds nothing to one that
     was later in the list we mark it as redundant.  The result is a
     minimal list of required features for the target
     architecture.  */

  std::list<candidate_extension *> extensions;

  auto_sbitmap target_isa_unsatisfied (isa_num_bits);
  bitmap_copy (target_isa_unsatisfied, target_isa);

  sbitmap isa_bits = NULL;
  for (const cpu_arch_extension *cand = selected_arch->common.extensions;
       cand->name != NULL;
       cand++)
    {
      if (cand->remove || cand->alias)
	continue;

      if (isa_bits == NULL)
	isa_bits = sbitmap_alloc (isa_num_bits);

      arm_initialize_isa (isa_bits, cand->isa_bits);
      if (bitmap_subset_p (isa_bits, target_isa))
	{
	  extensions.push_back (new candidate_extension (cand, isa_bits));
	  bitmap_and_compl (target_isa_unsatisfied, target_isa_unsatisfied,
			    isa_bits);
	  isa_bits = NULL;
	}
    }

  /* There's one extra case to consider, which is that the user has
     specified an FPU that is less capable than this architecture
     supports.  In that case the code above will fail to find a
     suitable feature.  We handle this by scanning the list of options
     again, matching the first option that provides an FPU that is
     more capable than the selected FPU.

     Note that the other case (user specified a more capable FPU than
     this architecture supports) should end up selecting the most
     capable FPU variant that we do support.  This is sufficient for
     multilib selection.  */

  if (bitmap_bit_p (target_isa_unsatisfied, isa_bit_vfpv2)
      && bitmap_bit_p (fpu_isa, isa_bit_vfpv2))
    {
      std::list<candidate_extension *>::iterator ipoint = extensions.begin ();

      for (const cpu_arch_extension *cand = selected_arch->common.extensions;
	   cand->name != NULL;
	   cand++)
	{
	  if (cand->remove || cand->alias)
	    continue;

	  if (isa_bits == NULL)
	    isa_bits = sbitmap_alloc (isa_num_bits);

	  /* We need to keep the features in canonical order, so move the
	     insertion point if this feature is a candidate.  */
	  if (ipoint != extensions.end ()
	      && (*ipoint)->extension == cand)
	    ++ipoint;

	  arm_initialize_isa (isa_bits, cand->isa_bits);
	  if (bitmap_subset_p (fpu_isa, isa_bits))
	    {
	      extensions.insert (ipoint,
				 new candidate_extension (cand, isa_bits));
	      isa_bits = NULL;
	      break;
	    }
	}
    }

  if (isa_bits)
    sbitmap_free (isa_bits);

  bitmap_clear (target_isa);
  size_t len = 1;
  for (std::list<candidate_extension *>::reverse_iterator riter
	 = extensions.rbegin ();
       riter != extensions.rend (); ++riter)
    {
      if (bitmap_subset_p ((*riter)->isa_bits, target_isa))
	(*riter)->required = false;
      else
	{
	  bitmap_ior (target_isa, target_isa, (*riter)->isa_bits);
	  len += strlen ((*riter)->extension->name) + 1;
	}
    }

  canonical_arch
    = (char *) xmalloc (len + strlen (selected_arch->common.name));

  strcpy (canonical_arch, selected_arch->common.name);

  for (std::list<candidate_extension *>::iterator iter = extensions.begin ();
       iter != extensions.end (); ++iter)
    {
      if ((*iter)->required)
	{
	  strcat (canonical_arch, "+");
	  strcat (canonical_arch, (*iter)->extension->name);
	}
      delete (*iter);
    }

  return canonical_arch;
}

/* If building big-endian on a BE8 target generate a --be8 option for
   the linker.  Takes four types of option: "little" - little-endian;
   "big" - big-endian; "be8" - force be8 iff big-endian; and "arch"
   "<arch-name>" (two arguments) - the target architecture.  The
   parameter names are generated by the driver from the command-line
   options.  */
const char *
arm_be8_option (int argc, const char **argv)
{
  int endian = TARGET_ENDIAN_DEFAULT;
  const char *arch = NULL;
  int arg;
  bool force = false;

  for (arg = 0; arg < argc; arg++)
    {
      if (strcmp (argv[arg], "little") == 0)
	endian = 0;
      else if (strcmp (argv[arg], "big") == 0)
	endian = 1;
      else if (strcmp (argv[arg], "be8") == 0)
	force = true;
      else if (strcmp (argv[arg], "arch") == 0)
	{
	  arg++;
	  gcc_assert (arg < argc);
	  arch = argv[arg];
	}
      else
	gcc_unreachable ();
    }

  /* Little endian - no be8 option.  */
  if (!endian)
    return "";

  if (force)
    return "--be8";

  /* Arch might not be set iff arm_canon_arch (above) detected an
     error.  Do nothing in that case.  */
  if (!arch)
    return "";

  const arch_option *selected_arch
    = arm_parse_arch_option_name (all_architectures, "-march", arch);

  /* Similarly if the given arch option was itself invalid.  */
  if (!selected_arch)
    return "";

  if (check_isa_bits_for (selected_arch->common.isa_bits, isa_bit_be8))
    return "--be8";

  return "";
}

/* Generate a -mfpu= option for passing to the assembler.  This is
   only called when -mfpu was set (possibly defaulted) to auto and is
   needed to ensure that the assembler knows the correct FPU to use.
   It wouldn't really be needed except that the compiler can be used
   to invoke the assembler directly on hand-written files that lack
   the necessary internal .fpu directives.  We assume that the architecture
   canonicalization calls have already been made so that we have a final
   -march= option to derive the fpu from.  */
const char*
arm_asm_auto_mfpu (int argc, const char **argv)
{
  static char *auto_fpu = NULL;
  const char *arch = NULL;
  static const enum isa_feature fpu_bitlist[]
    = { ISA_ALL_FPU_INTERNAL, isa_nobit };
  const arch_option *selected_arch;
  static const char* fpuname = "softvfp";

  /* Handle multiple calls to this routine.  */
  if (auto_fpu)
    {
      free (auto_fpu);
      auto_fpu = NULL;
    }

  while (argc)
    {
      if (strcmp (argv[0], "arch") == 0)
	arch = argv[1];
      else
	fatal_error (input_location,
		     "unrecognized operand to %%:asm_auto_mfpu");
      argc -= 2;
      argv += 2;
    }

  auto_sbitmap target_isa (isa_num_bits);
  auto_sbitmap fpubits (isa_num_bits);

  gcc_assert (arch != NULL);
  selected_arch = arm_parse_arch_option_name (all_architectures,
					      "-march", arch);
  if (selected_arch == NULL)
    return "";

  arm_initialize_isa (target_isa, selected_arch->common.isa_bits);
  arm_parse_option_features (target_isa, &selected_arch->common,
			     strchr (arch, '+'));
  arm_initialize_isa (fpubits, fpu_bitlist);

  bitmap_and (fpubits, fpubits, target_isa);

  /* The logic below is essentially identical to that in
     arm.c:arm_identify_fpu_from_isa(), but that only works in the main
     part of the compiler.  */

  /* If there are no FPU capability bits, we just pass -mfpu=softvfp.  */
  if (!bitmap_empty_p (fpubits))
    {
      unsigned int i;
      auto_sbitmap cand_fpubits (isa_num_bits);
      for (i = 0; i < TARGET_FPU_auto; i++)
	{
	  arm_initialize_isa (cand_fpubits, all_fpus[i].isa_bits);
	  if (bitmap_equal_p (fpubits, cand_fpubits))
	    {
	      fpuname = all_fpus[i].name;
	      break;
	    }
	}

      gcc_assert (i != TARGET_FPU_auto);
    }

  auto_fpu = (char *) xmalloc (strlen (fpuname) + sizeof ("-mfpu="));
  strcpy (auto_fpu, "-mfpu=");
  strcat (auto_fpu, fpuname);
  return auto_fpu;
}

#undef ARM_CPU_NAME_LENGTH


#undef  TARGET_DEFAULT_TARGET_FLAGS
#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_SCHED_PROLOG)

#undef  TARGET_OPTION_OPTIMIZATION_TABLE
#define TARGET_OPTION_OPTIMIZATION_TABLE arm_option_optimization_table

#undef TARGET_EXCEPT_UNWIND_INFO
#define TARGET_EXCEPT_UNWIND_INFO  arm_except_unwind_info

struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
