[07/11] aarch64: Move arch/cpu parsing to aarch64-common.cc

Message ID 0ff2bf8c-a557-5b90-8e2e-d10885e277bf@e124511.cambridge.arm.com
State New
Headers
Series aarch64: Refactor target parsing |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Test passed

Commit Message

Andrew Carlotti Jan. 10, 2025, 5:23 p.m. UTC
  Aside from moving the functions, the only changes are to make them
non-static, and to use the existing info arrays within aarch64-common.cc
instead of the info arrays remaining in aarch64.cc.

gcc/ChangeLog:

	* common/config/aarch64/aarch64-common.cc
	(aarch64_get_all_extension_candidates): Move within file.
	(aarch64_print_hint_for_extensions): Move from aarch64.cc.
	(aarch64_print_hint_for_arch): Ditto.
	(aarch64_print_hint_for_core): Ditto.
	(enum aarch_parse_opt_result): Ditto.
	(aarch64_parse_arch): Ditto.
	(aarch64_parse_cpu): Ditto.
	(aarch64_parse_tune): Ditto.
	(aarch64_validate_march): Ditto.
	(aarch64_validate_mcpu): Ditto.
	(aarch64_validate_mtune): Ditto.
	* config/aarch64/aarch64-protos.h
	(aarch64_rewrite_selected_cpu): Move within file.
	(aarch64_print_hint_for_extensions): Share function prototype.
	(aarch64_print_hint_for_arch): Ditto.
	(aarch64_print_hint_for_core): Ditto.
	(enum aarch_parse_opt_result): Ditto.
	(aarch64_validate_march): Ditto.
	(aarch64_validate_mcpu): Ditto.
	(aarch64_validate_mtune): Ditto.
	(aarch64_get_all_extension_candidates): Unshare prototype.
	* config/aarch64/aarch64.cc
	(aarch64_parse_arch): Move to aarch64-common.cc.
	(aarch64_parse_cpu): Ditto.
	(aarch64_parse_tune): Ditto.
	(aarch64_print_hint_for_core): Ditto.
	(aarch64_print_hint_for_arch): Ditto.
	(aarch64_print_hint_for_extensions): Ditto.
	(aarch64_validate_mcpu): Ditto.
	(aarch64_validate_march): Ditto.
	(aarch64_validate_mtune): Ditto.
  

Comments

Richard Sandiford Jan. 14, 2025, 6:14 p.m. UTC | #1
Andrew Carlotti <andrew.carlotti@arm.com> writes:
> Aside from moving the functions, the only changes are to make them
> non-static, and to use the existing info arrays within aarch64-common.cc
> instead of the info arrays remaining in aarch64.cc.
>
> gcc/ChangeLog:
>
> 	* common/config/aarch64/aarch64-common.cc
> 	(aarch64_get_all_extension_candidates): Move within file.
> 	(aarch64_print_hint_for_extensions): Move from aarch64.cc.
> 	(aarch64_print_hint_for_arch): Ditto.
> 	(aarch64_print_hint_for_core): Ditto.
> 	(enum aarch_parse_opt_result): Ditto.
> 	(aarch64_parse_arch): Ditto.
> 	(aarch64_parse_cpu): Ditto.
> 	(aarch64_parse_tune): Ditto.
> 	(aarch64_validate_march): Ditto.
> 	(aarch64_validate_mcpu): Ditto.
> 	(aarch64_validate_mtune): Ditto.
> 	* config/aarch64/aarch64-protos.h
> 	(aarch64_rewrite_selected_cpu): Move within file.
> 	(aarch64_print_hint_for_extensions): Share function prototype.
> 	(aarch64_print_hint_for_arch): Ditto.
> 	(aarch64_print_hint_for_core): Ditto.
> 	(enum aarch_parse_opt_result): Ditto.
> 	(aarch64_validate_march): Ditto.
> 	(aarch64_validate_mcpu): Ditto.
> 	(aarch64_validate_mtune): Ditto.
> 	(aarch64_get_all_extension_candidates): Unshare prototype.
> 	* config/aarch64/aarch64.cc
> 	(aarch64_parse_arch): Move to aarch64-common.cc.
> 	(aarch64_parse_cpu): Ditto.
> 	(aarch64_parse_tune): Ditto.
> 	(aarch64_print_hint_for_core): Ditto.
> 	(aarch64_print_hint_for_arch): Ditto.
> 	(aarch64_print_hint_for_extensions): Ditto.
> 	(aarch64_validate_mcpu): Ditto.
> 	(aarch64_validate_march): Ditto.
> 	(aarch64_validate_mtune): Ditto.

OK, thanks.

Richard

> diff --git a/gcc/common/config/aarch64/aarch64-common.cc b/gcc/common/config/aarch64/aarch64-common.cc
> index 4f4e363539b7b9311bfcb7a8b30b706000e50352..5cc00cd3b72807ec439c9c72af297d1ff5b2b679 100644
> --- a/gcc/common/config/aarch64/aarch64-common.cc
> +++ b/gcc/common/config/aarch64/aarch64-common.cc
> @@ -205,6 +205,85 @@ static constexpr processor_info all_cores[] =
>  };
>  
>  
> +/* Append all architecture extension candidates to the CANDIDATES vector.  */
> +
> +void
> +aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates)
> +{
> +  const struct extension_info *opt;
> +  for (opt = all_extensions; opt->name != NULL; opt++)
> +    candidates->safe_push (opt->name);
> +}
> +
> +/* Print a hint with a suggestion for an extension name
> +   that most closely resembles what the user passed in STR.  */
> +
> +void
> +aarch64_print_hint_for_extensions (const char *str)
> +{
> +  auto_vec<const char *> candidates;
> +  aarch64_get_all_extension_candidates (&candidates);
> +  char *s;
> +  const char *hint = candidates_list_and_hint (str, 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);
> +}
> +
> +/* Print a hint with a suggestion for an architecture name that most closely
> +   resembles what the user passed in STR.  */
> +
> +void
> +aarch64_print_hint_for_arch (const char *str)
> +{
> +  auto_vec<const char *> candidates;
> +  const struct arch_info *entry = all_architectures;
> +  for (; entry->name != NULL; entry++)
> +    candidates.safe_push (entry->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 (str, 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);
> +}
> +
> +/* Print a hint with a suggestion for a core name that most closely resembles
> +   what the user passed in STR.  */
> +
> +void
> +aarch64_print_hint_for_core (const char *str)
> +{
> +  auto_vec<const char *> candidates;
> +  const struct processor_info *entry = all_cores;
> +  for (; entry->name != NULL; entry++)
> +    candidates.safe_push (entry->name);
> +
> +  char *s;
> +  const char *hint = candidates_list_and_hint (str, 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 architecture extension string STR and update ISA_FLAGS
>     with the architecture features turned on or off.  Return a
>     aarch_parse_opt_result describing the result.
> @@ -275,16 +354,266 @@ aarch64_parse_extension (const char *str, aarch64_feature_flags *isa_flags,
>    return AARCH_PARSE_OK;
>  }
>  
> -/* Append all architecture extension candidates to the CANDIDATES vector.  */
> +/* Parse the TO_PARSE string and put the architecture that it
> +   selects into RES_ARCH and the architectural features into RES_FLAGS.
> +   Return an aarch_parse_opt_result describing the parse result.
> +   If there is an error parsing, RES_ARCH and RES_FLAGS are left unchanged.
> +   When the TO_PARSE string contains an invalid extension,
> +   a copy of the string is created and stored to INVALID_EXTENSION.  */
>  
> -void
> -aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates)
> +enum aarch_parse_opt_result
> +aarch64_parse_arch (const char *to_parse, aarch64_arch *res_arch,
> +		    aarch64_feature_flags *res_flags,
> +		    std::string *invalid_extension)
>  {
> -  const struct extension_info *opt;
> -  for (opt = all_extensions; opt->name != NULL; opt++)
> -    candidates->safe_push (opt->name);
> +  const char *ext;
> +  const struct arch_info *arch;
> +  size_t len;
> +
> +  ext = strchr (to_parse, '+');
> +
> +  if (ext != NULL)
> +    len = ext - to_parse;
> +  else
> +    len = strlen (to_parse);
> +
> +  if (len == 0)
> +    return AARCH_PARSE_MISSING_ARG;
> +
> +
> +  /* Loop through the list of supported ARCHes to find a match.  */
> +  for (arch = all_architectures; arch->name != NULL; arch++)
> +    {
> +      if (strlen (arch->name) == len
> +	  && strncmp (arch->name, to_parse, len) == 0)
> +	{
> +	  auto isa_flags = arch->flags;
> +
> +	  if (ext != NULL)
> +	    {
> +	      /* TO_PARSE string contains at least one extension.  */
> +	      enum aarch_parse_opt_result ext_res
> +		= aarch64_parse_extension (ext, &isa_flags, invalid_extension);
> +
> +	      if (ext_res != AARCH_PARSE_OK)
> +		return ext_res;
> +	    }
> +	  /* Extension parsing was successful.  Confirm the result
> +	     arch and ISA flags.  */
> +	  *res_arch = arch->arch;
> +	  *res_flags = isa_flags;
> +	  return AARCH_PARSE_OK;
> +	}
> +    }
> +
> +  /* ARCH name not found in list.  */
> +  return AARCH_PARSE_INVALID_ARG;
> +}
> +
> +/* Parse the TO_PARSE string and put the result tuning in RES_CPU and the
> +   architecture flags in RES_FLAGS.  Return an aarch_parse_opt_result
> +   describing the parse result.  If there is an error parsing, RES_CPU and
> +   RES_FLAGS are left unchanged.
> +   When the TO_PARSE string contains an invalid extension,
> +   a copy of the string is created and stored to INVALID_EXTENSION.  */
> +
> +enum aarch_parse_opt_result
> +aarch64_parse_cpu (const char *to_parse, aarch64_cpu *res_cpu,
> +		   aarch64_feature_flags *res_flags,
> +		   std::string *invalid_extension)
> +{
> +  const char *ext;
> +  const struct processor_info *cpu;
> +  size_t len;
> +
> +  ext = strchr (to_parse, '+');
> +
> +  if (ext != NULL)
> +    len = ext - to_parse;
> +  else
> +    len = strlen (to_parse);
> +
> +  if (len == 0)
> +    return AARCH_PARSE_MISSING_ARG;
> +
> +
> +  /* Loop through the list of supported CPUs to find a match.  */
> +  for (cpu = all_cores; cpu->name != NULL; cpu++)
> +    {
> +      if (strlen (cpu->name) == len && strncmp (cpu->name, to_parse, len) == 0)
> +	{
> +	  auto isa_flags = cpu->flags;
> +
> +	  if (ext != NULL)
> +	    {
> +	      /* TO_PARSE string contains at least one extension.  */
> +	      enum aarch_parse_opt_result ext_res
> +		= aarch64_parse_extension (ext, &isa_flags, invalid_extension);
> +
> +	      if (ext_res != AARCH_PARSE_OK)
> +		return ext_res;
> +	    }
> +	  /* Extension parsing was successfull.  Confirm the result
> +	     cpu and ISA flags.  */
> +	  *res_cpu = cpu->processor;
> +	  *res_flags = isa_flags;
> +	  return AARCH_PARSE_OK;
> +	}
> +    }
> +
> +  /* CPU name not found in list.  */
> +  return AARCH_PARSE_INVALID_ARG;
>  }
>  
> +/* Parse the TO_PARSE string and put the cpu it selects into RES_CPU.
> +   Return an aarch_parse_opt_result describing the parse result.
> +   If the parsing fails then RES_CPU does not change.  */
> +
> +enum aarch_parse_opt_result
> +aarch64_parse_tune (const char *to_parse, aarch64_cpu *res_cpu)
> +{
> +  const struct processor_info *cpu;
> +
> +  /* Loop through the list of supported CPUs to find a match.  */
> +  for (cpu = all_cores; cpu->name != NULL; cpu++)
> +    {
> +      if (strcmp (cpu->name, to_parse) == 0)
> +	{
> +	  *res_cpu = cpu->processor;
> +	  return AARCH_PARSE_OK;
> +	}
> +    }
> +
> +  /* CPU name not found in list.  */
> +  return AARCH_PARSE_INVALID_ARG;
> +}
> +
> +
> +/* Validate a command-line -march option.  Parse the arch and extensions
> +   (if any) specified in STR and throw errors if appropriate.  Put the
> +   results, if they are valid, in RES_ARCH and RES_FLAGS.  Return whether the
> +   option is valid.  */
> +
> +bool
> +aarch64_validate_march (const char *str, aarch64_arch *res_arch,
> +			aarch64_feature_flags *res_flags)
> +{
> +  std::string invalid_extension;
> +  enum aarch_parse_opt_result parse_res
> +    = aarch64_parse_arch (str, res_arch, res_flags, &invalid_extension);
> +
> +  if (parse_res == AARCH_PARSE_OK)
> +    return true;
> +
> +  switch (parse_res)
> +    {
> +      case AARCH_PARSE_MISSING_ARG:
> +	error ("missing arch name in %<-march=%s%>", str);
> +	break;
> +      case AARCH_PARSE_INVALID_ARG:
> +	{
> +	  error ("unknown value %qs for %<-march%>", str);
> +	  aarch64_print_hint_for_arch (str);
> +	  /* A common user error is confusing -march and -mcpu.
> +	     If the -march string matches a known CPU suggest -mcpu.  */
> +	  aarch64_cpu temp_cpu;
> +	  aarch64_feature_flags temp_flags;
> +	  parse_res = aarch64_parse_cpu (str, &temp_cpu, &temp_flags,
> +					 &invalid_extension);
> +	  if (parse_res == AARCH_PARSE_OK)
> +	    inform (input_location, "did you mean %<-mcpu=%s%>?", str);
> +	  break;
> +	}
> +      case AARCH_PARSE_INVALID_FEATURE:
> +	error ("invalid feature modifier %qs in %<-march=%s%>",
> +	       invalid_extension.c_str (), str);
> +	aarch64_print_hint_for_extensions (invalid_extension.c_str ());
> +	break;
> +      default:
> +	gcc_unreachable ();
> +    }
> +
> +  return false;
> +}
> +
> +/* Validate a command-line -mcpu option.  Parse the cpu and extensions (if any)
> +   specified in STR and throw errors if appropriate.  Put the results if
> +   they are valid in RES_CPU and RES_FLAGS.  Return whether the option is
> +   valid.  */
> +
> +bool
> +aarch64_validate_mcpu (const char *str, aarch64_cpu *res_cpu,
> +		       aarch64_feature_flags *res_flags)
> +{
> +  std::string invalid_extension;
> +  enum aarch_parse_opt_result parse_res
> +    = aarch64_parse_cpu (str, res_cpu, res_flags, &invalid_extension);
> +
> +  if (parse_res == AARCH_PARSE_OK)
> +    return true;
> +
> +  switch (parse_res)
> +    {
> +      case AARCH_PARSE_MISSING_ARG:
> +	error ("missing cpu name in %<-mcpu=%s%>", str);
> +	break;
> +      case AARCH_PARSE_INVALID_ARG:
> +	{
> +	  error ("unknown value %qs for %<-mcpu%>", str);
> +	  aarch64_print_hint_for_core (str);
> +	  /* A common user error is confusing -march and -mcpu.
> +	     If the -mcpu string matches a known architecture then suggest
> +	     -march=.  */
> +	  aarch64_arch temp_arch;
> +	  aarch64_feature_flags temp_flags;
> +	  parse_res = aarch64_parse_arch (str, &temp_arch, &temp_flags,
> +					  &invalid_extension);
> +	  if (parse_res == AARCH_PARSE_OK)
> +	    inform (input_location, "did you mean %<-march=%s%>?", str);
> +	  break;
> +	}
> +      case AARCH_PARSE_INVALID_FEATURE:
> +	error ("invalid feature modifier %qs in %<-mcpu=%s%>",
> +	       invalid_extension.c_str (), str);
> +	aarch64_print_hint_for_extensions (invalid_extension.c_str ());
> +	break;
> +      default:
> +	gcc_unreachable ();
> +    }
> +
> +  return false;
> +}
> +
> +/* Validate a command-line -mtune option.  Parse the cpu
> +   specified in STR and throw errors if appropriate.  Put the
> +   result, if it is valid, in RES_CPU.  Return whether the option is
> +   valid.  */
> +
> +bool
> +aarch64_validate_mtune (const char *str, aarch64_cpu *res_cpu)
> +{
> +  enum aarch_parse_opt_result parse_res
> +    = aarch64_parse_tune (str, res_cpu);
> +
> +  if (parse_res == AARCH_PARSE_OK)
> +    return true;
> +
> +  switch (parse_res)
> +    {
> +      case AARCH_PARSE_MISSING_ARG:
> +	error ("missing cpu name in %<-mtune=%s%>", str);
> +	break;
> +      case AARCH_PARSE_INVALID_ARG:
> +	error ("unknown value %qs for %<-mtune%>", str);
> +	aarch64_print_hint_for_core (str);
> +	break;
> +      default:
> +	gcc_unreachable ();
> +    }
> +  return false;
> +}
> +
> +
>  /* Return a string representation of ISA_FLAGS.  DEFAULT_ARCH_FLAGS
>     gives the default set of flags which are implied by whatever -march
>     we'd put out.  Our job is to figure out the minimal set of "+" and
> diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
> index fa7bc8029be04f6530d2aee2ead4d754ba3b2550..4114fc9b3b7645b8781257f6f775ddfe7e8c339e 100644
> --- a/gcc/config/aarch64/aarch64-protos.h
> +++ b/gcc/config/aarch64/aarch64-protos.h
> @@ -1190,11 +1190,27 @@ void aarch64_set_asm_isa_flags (aarch64_feature_flags);
>  void aarch64_set_asm_isa_flags (gcc_options *, aarch64_feature_flags);
>  bool aarch64_handle_option (struct gcc_options *, struct gcc_options *,
>  			     const struct cl_decoded_option *, location_t);
> -const char *aarch64_rewrite_selected_cpu (const char *name);
> +void aarch64_print_hint_for_extensions (const char *);
> +void aarch64_print_hint_for_arch (const char *);
> +void aarch64_print_hint_for_core (const char *);
>  enum aarch_parse_opt_result aarch64_parse_extension (const char *,
>                                                       aarch64_feature_flags *,
>                                                       std::string *);
> -void aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates);
> +enum aarch_parse_opt_result aarch64_parse_arch (const char *,
> +						aarch64_arch *,
> +						aarch64_feature_flags *,
> +						std::string *);
> +enum aarch_parse_opt_result aarch64_parse_cpu (const char *,
> +					       aarch64_cpu *,
> +					       aarch64_feature_flags *,
> +					       std::string *);
> +enum aarch_parse_opt_result aarch64_parse_tune (const char *, aarch64_cpu *);
> +bool aarch64_validate_march (const char *, aarch64_arch *,
> +			     aarch64_feature_flags *);
> +bool aarch64_validate_mcpu (const char *, aarch64_cpu *,
> +			    aarch64_feature_flags *);
> +bool aarch64_validate_mtune (const char *, aarch64_cpu *);
> +const char *aarch64_rewrite_selected_cpu (const char *name);
>  std::string aarch64_get_extension_string_for_isa_flags (aarch64_feature_flags,
>  							aarch64_feature_flags);
>  
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index f33034cbb205eb52b5ee5965b8b972cedf6f4927..75ba66a979c979fd01948b0a2066a15371df9bfa 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -18217,140 +18217,6 @@ better_main_loop_than_p (const vector_costs *uncast_other) const
>  
>  static void initialize_aarch64_code_model (struct gcc_options *);
>  
> -/* Parse the TO_PARSE string and put the architecture that it
> -   selects into RES_ARCH and the architectural features into RES_FLAGS.
> -   Return an aarch_parse_opt_result describing the parse result.
> -   If there is an error parsing, RES_ARCH and RES_FLAGS are left unchanged.
> -   When the TO_PARSE string contains an invalid extension,
> -   a copy of the string is created and stored to INVALID_EXTENSION.  */
> -
> -static enum aarch_parse_opt_result
> -aarch64_parse_arch (const char *to_parse, aarch64_arch *res_arch,
> -		    aarch64_feature_flags *res_flags,
> -		    std::string *invalid_extension)
> -{
> -  const char *ext;
> -  const struct processor *arch;
> -  size_t len;
> -
> -  ext = strchr (to_parse, '+');
> -
> -  if (ext != NULL)
> -    len = ext - to_parse;
> -  else
> -    len = strlen (to_parse);
> -
> -  if (len == 0)
> -    return AARCH_PARSE_MISSING_ARG;
> -
> -
> -  /* Loop through the list of supported ARCHes to find a match.  */
> -  for (arch = all_architectures; arch->name != NULL; arch++)
> -    {
> -      if (strlen (arch->name) == len
> -	  && strncmp (arch->name, to_parse, len) == 0)
> -	{
> -	  auto isa_flags = arch->flags;
> -
> -	  if (ext != NULL)
> -	    {
> -	      /* TO_PARSE string contains at least one extension.  */
> -	      enum aarch_parse_opt_result ext_res
> -		= aarch64_parse_extension (ext, &isa_flags, invalid_extension);
> -
> -	      if (ext_res != AARCH_PARSE_OK)
> -		return ext_res;
> -	    }
> -	  /* Extension parsing was successful.  Confirm the result
> -	     arch and ISA flags.  */
> -	  *res_arch = arch->arch;
> -	  *res_flags = isa_flags;
> -	  return AARCH_PARSE_OK;
> -	}
> -    }
> -
> -  /* ARCH name not found in list.  */
> -  return AARCH_PARSE_INVALID_ARG;
> -}
> -
> -/* Parse the TO_PARSE string and put the result tuning in RES_CPU and the
> -   architecture flags in RES_FLAGS.  Return an aarch_parse_opt_result
> -   describing the parse result.  If there is an error parsing, RES_CPU and
> -   RES_FLAGS are left unchanged.
> -   When the TO_PARSE string contains an invalid extension,
> -   a copy of the string is created and stored to INVALID_EXTENSION.  */
> -
> -static enum aarch_parse_opt_result
> -aarch64_parse_cpu (const char *to_parse, aarch64_cpu *res_cpu,
> -		   aarch64_feature_flags *res_flags,
> -		   std::string *invalid_extension)
> -{
> -  const char *ext;
> -  const struct processor *cpu;
> -  size_t len;
> -
> -  ext = strchr (to_parse, '+');
> -
> -  if (ext != NULL)
> -    len = ext - to_parse;
> -  else
> -    len = strlen (to_parse);
> -
> -  if (len == 0)
> -    return AARCH_PARSE_MISSING_ARG;
> -
> -
> -  /* Loop through the list of supported CPUs to find a match.  */
> -  for (cpu = all_cores; cpu->name != NULL; cpu++)
> -    {
> -      if (strlen (cpu->name) == len && strncmp (cpu->name, to_parse, len) == 0)
> -	{
> -	  auto isa_flags = cpu->flags;
> -
> -	  if (ext != NULL)
> -	    {
> -	      /* TO_PARSE string contains at least one extension.  */
> -	      enum aarch_parse_opt_result ext_res
> -		= aarch64_parse_extension (ext, &isa_flags, invalid_extension);
> -
> -	      if (ext_res != AARCH_PARSE_OK)
> -		return ext_res;
> -	    }
> -	  /* Extension parsing was successfull.  Confirm the result
> -	     cpu and ISA flags.  */
> -	  *res_cpu = cpu->ident;
> -	  *res_flags = isa_flags;
> -	  return AARCH_PARSE_OK;
> -	}
> -    }
> -
> -  /* CPU name not found in list.  */
> -  return AARCH_PARSE_INVALID_ARG;
> -}
> -
> -/* Parse the TO_PARSE string and put the cpu it selects into RES_CPU.
> -   Return an aarch_parse_opt_result describing the parse result.
> -   If the parsing fails then RES_CPU does not change.  */
> -
> -static enum aarch_parse_opt_result
> -aarch64_parse_tune (const char *to_parse, aarch64_cpu *res_cpu)
> -{
> -  const struct processor *cpu;
> -
> -  /* Loop through the list of supported CPUs to find a match.  */
> -  for (cpu = all_cores; cpu->name != NULL; cpu++)
> -    {
> -      if (strcmp (cpu->name, to_parse) == 0)
> -	{
> -	  *res_cpu = cpu->ident;
> -	  return AARCH_PARSE_OK;
> -	}
> -    }
> -
> -  /* CPU name not found in list.  */
> -  return AARCH_PARSE_INVALID_ARG;
> -}
> -
>  /* Parse TOKEN, which has length LENGTH to see if it is an option
>     described in FLAG.  If it is, return the index bit for that fusion type.
>     If not, error (printing OPTION_NAME) and return zero.  */
> @@ -18884,123 +18750,6 @@ aarch64_override_options_internal (struct gcc_options *opts)
>    aarch64_override_options_after_change_1 (opts);
>  }
>  
> -/* Print a hint with a suggestion for a core name that most closely resembles
> -   what the user passed in STR.  */
> -
> -inline static void
> -aarch64_print_hint_for_core (const char *str)
> -{
> -  auto_vec<const char *> candidates;
> -  const struct processor *entry = all_cores;
> -  for (; entry->name != NULL; entry++)
> -    candidates.safe_push (entry->name);
> -
> -  char *s;
> -  const char *hint = candidates_list_and_hint (str, 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);
> -}
> -
> -/* Print a hint with a suggestion for an architecture name that most closely
> -   resembles what the user passed in STR.  */
> -
> -inline static void
> -aarch64_print_hint_for_arch (const char *str)
> -{
> -  auto_vec<const char *> candidates;
> -  const struct processor *entry = all_architectures;
> -  for (; entry->name != NULL; entry++)
> -    candidates.safe_push (entry->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 (str, 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);
> -}
> -
> -
> -/* Print a hint with a suggestion for an extension name
> -   that most closely resembles what the user passed in STR.  */
> -
> -void
> -aarch64_print_hint_for_extensions (const char *str)
> -{
> -  auto_vec<const char *> candidates;
> -  aarch64_get_all_extension_candidates (&candidates);
> -  char *s;
> -  const char *hint = candidates_list_and_hint (str, 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);
> -}
> -
> -/* Validate a command-line -mcpu option.  Parse the cpu and extensions (if any)
> -   specified in STR and throw errors if appropriate.  Put the results if
> -   they are valid in RES_CPU and RES_FLAGS.  Return whether the option is
> -   valid.  */
> -
> -static bool
> -aarch64_validate_mcpu (const char *str, aarch64_cpu *res_cpu,
> -		       aarch64_feature_flags *res_flags)
> -{
> -  std::string invalid_extension;
> -  enum aarch_parse_opt_result parse_res
> -    = aarch64_parse_cpu (str, res_cpu, res_flags, &invalid_extension);
> -
> -  if (parse_res == AARCH_PARSE_OK)
> -    return true;
> -
> -  switch (parse_res)
> -    {
> -      case AARCH_PARSE_MISSING_ARG:
> -	error ("missing cpu name in %<-mcpu=%s%>", str);
> -	break;
> -      case AARCH_PARSE_INVALID_ARG:
> -	{
> -	  error ("unknown value %qs for %<-mcpu%>", str);
> -	  aarch64_print_hint_for_core (str);
> -	  /* A common user error is confusing -march and -mcpu.
> -	     If the -mcpu string matches a known architecture then suggest
> -	     -march=.  */
> -	  aarch64_arch temp_arch;
> -	  aarch64_feature_flags temp_flags;
> -	  parse_res = aarch64_parse_arch (str, &temp_arch, &temp_flags,
> -					  &invalid_extension);
> -	  if (parse_res == AARCH_PARSE_OK)
> -	    inform (input_location, "did you mean %<-march=%s%>?", str);
> -	  break;
> -	}
> -      case AARCH_PARSE_INVALID_FEATURE:
> -	error ("invalid feature modifier %qs in %<-mcpu=%s%>",
> -	       invalid_extension.c_str (), str);
> -	aarch64_print_hint_for_extensions (invalid_extension.c_str ());
> -	break;
> -      default:
> -	gcc_unreachable ();
> -    }
> -
> -  return false;
> -}
> -
>  /* Straight line speculation indicators.  */
>  enum aarch64_sls_hardening_type
>  {
> @@ -19074,82 +18823,6 @@ aarch64_validate_sls_mitigation (const char *const_str)
>    free (str_root);
>  }
>  
> -/* Validate a command-line -march option.  Parse the arch and extensions
> -   (if any) specified in STR and throw errors if appropriate.  Put the
> -   results, if they are valid, in RES_ARCH and RES_FLAGS.  Return whether the
> -   option is valid.  */
> -
> -static bool
> -aarch64_validate_march (const char *str, aarch64_arch *res_arch,
> -			aarch64_feature_flags *res_flags)
> -{
> -  std::string invalid_extension;
> -  enum aarch_parse_opt_result parse_res
> -    = aarch64_parse_arch (str, res_arch, res_flags, &invalid_extension);
> -
> -  if (parse_res == AARCH_PARSE_OK)
> -    return true;
> -
> -  switch (parse_res)
> -    {
> -      case AARCH_PARSE_MISSING_ARG:
> -	error ("missing arch name in %<-march=%s%>", str);
> -	break;
> -      case AARCH_PARSE_INVALID_ARG:
> -	{
> -	  error ("unknown value %qs for %<-march%>", str);
> -	  aarch64_print_hint_for_arch (str);
> -	  /* A common user error is confusing -march and -mcpu.
> -	     If the -march string matches a known CPU suggest -mcpu.  */
> -	  aarch64_cpu temp_cpu;
> -	  aarch64_feature_flags temp_flags;
> -	  parse_res = aarch64_parse_cpu (str, &temp_cpu, &temp_flags,
> -					 &invalid_extension);
> -	  if (parse_res == AARCH_PARSE_OK)
> -	    inform (input_location, "did you mean %<-mcpu=%s%>?", str);
> -	  break;
> -	}
> -      case AARCH_PARSE_INVALID_FEATURE:
> -	error ("invalid feature modifier %qs in %<-march=%s%>",
> -	       invalid_extension.c_str (), str);
> -	aarch64_print_hint_for_extensions (invalid_extension.c_str ());
> -	break;
> -      default:
> -	gcc_unreachable ();
> -    }
> -
> -  return false;
> -}
> -
> -/* Validate a command-line -mtune option.  Parse the cpu
> -   specified in STR and throw errors if appropriate.  Put the
> -   result, if it is valid, in RES_CPU.  Return whether the option is
> -   valid.  */
> -
> -static bool
> -aarch64_validate_mtune (const char *str, aarch64_cpu *res_cpu)
> -{
> -  enum aarch_parse_opt_result parse_res
> -    = aarch64_parse_tune (str, res_cpu);
> -
> -  if (parse_res == AARCH_PARSE_OK)
> -    return true;
> -
> -  switch (parse_res)
> -    {
> -      case AARCH_PARSE_MISSING_ARG:
> -	error ("missing cpu name in %<-mtune=%s%>", str);
> -	break;
> -      case AARCH_PARSE_INVALID_ARG:
> -	error ("unknown value %qs for %<-mtune%>", str);
> -	aarch64_print_hint_for_core (str);
> -	break;
> -      default:
> -	gcc_unreachable ();
> -    }
> -  return false;
> -}
> -
>  /* Return the VG value associated with -msve-vector-bits= value VALUE.  */
>  
>  static poly_uint16
  

Patch

diff --git a/gcc/common/config/aarch64/aarch64-common.cc b/gcc/common/config/aarch64/aarch64-common.cc
index 4f4e363539b7b9311bfcb7a8b30b706000e50352..5cc00cd3b72807ec439c9c72af297d1ff5b2b679 100644
--- a/gcc/common/config/aarch64/aarch64-common.cc
+++ b/gcc/common/config/aarch64/aarch64-common.cc
@@ -205,6 +205,85 @@  static constexpr processor_info all_cores[] =
 };
 
 
+/* Append all architecture extension candidates to the CANDIDATES vector.  */
+
+void
+aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates)
+{
+  const struct extension_info *opt;
+  for (opt = all_extensions; opt->name != NULL; opt++)
+    candidates->safe_push (opt->name);
+}
+
+/* Print a hint with a suggestion for an extension name
+   that most closely resembles what the user passed in STR.  */
+
+void
+aarch64_print_hint_for_extensions (const char *str)
+{
+  auto_vec<const char *> candidates;
+  aarch64_get_all_extension_candidates (&candidates);
+  char *s;
+  const char *hint = candidates_list_and_hint (str, 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);
+}
+
+/* Print a hint with a suggestion for an architecture name that most closely
+   resembles what the user passed in STR.  */
+
+void
+aarch64_print_hint_for_arch (const char *str)
+{
+  auto_vec<const char *> candidates;
+  const struct arch_info *entry = all_architectures;
+  for (; entry->name != NULL; entry++)
+    candidates.safe_push (entry->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 (str, 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);
+}
+
+/* Print a hint with a suggestion for a core name that most closely resembles
+   what the user passed in STR.  */
+
+void
+aarch64_print_hint_for_core (const char *str)
+{
+  auto_vec<const char *> candidates;
+  const struct processor_info *entry = all_cores;
+  for (; entry->name != NULL; entry++)
+    candidates.safe_push (entry->name);
+
+  char *s;
+  const char *hint = candidates_list_and_hint (str, 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 architecture extension string STR and update ISA_FLAGS
    with the architecture features turned on or off.  Return a
    aarch_parse_opt_result describing the result.
@@ -275,16 +354,266 @@  aarch64_parse_extension (const char *str, aarch64_feature_flags *isa_flags,
   return AARCH_PARSE_OK;
 }
 
-/* Append all architecture extension candidates to the CANDIDATES vector.  */
+/* Parse the TO_PARSE string and put the architecture that it
+   selects into RES_ARCH and the architectural features into RES_FLAGS.
+   Return an aarch_parse_opt_result describing the parse result.
+   If there is an error parsing, RES_ARCH and RES_FLAGS are left unchanged.
+   When the TO_PARSE string contains an invalid extension,
+   a copy of the string is created and stored to INVALID_EXTENSION.  */
 
-void
-aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates)
+enum aarch_parse_opt_result
+aarch64_parse_arch (const char *to_parse, aarch64_arch *res_arch,
+		    aarch64_feature_flags *res_flags,
+		    std::string *invalid_extension)
 {
-  const struct extension_info *opt;
-  for (opt = all_extensions; opt->name != NULL; opt++)
-    candidates->safe_push (opt->name);
+  const char *ext;
+  const struct arch_info *arch;
+  size_t len;
+
+  ext = strchr (to_parse, '+');
+
+  if (ext != NULL)
+    len = ext - to_parse;
+  else
+    len = strlen (to_parse);
+
+  if (len == 0)
+    return AARCH_PARSE_MISSING_ARG;
+
+
+  /* Loop through the list of supported ARCHes to find a match.  */
+  for (arch = all_architectures; arch->name != NULL; arch++)
+    {
+      if (strlen (arch->name) == len
+	  && strncmp (arch->name, to_parse, len) == 0)
+	{
+	  auto isa_flags = arch->flags;
+
+	  if (ext != NULL)
+	    {
+	      /* TO_PARSE string contains at least one extension.  */
+	      enum aarch_parse_opt_result ext_res
+		= aarch64_parse_extension (ext, &isa_flags, invalid_extension);
+
+	      if (ext_res != AARCH_PARSE_OK)
+		return ext_res;
+	    }
+	  /* Extension parsing was successful.  Confirm the result
+	     arch and ISA flags.  */
+	  *res_arch = arch->arch;
+	  *res_flags = isa_flags;
+	  return AARCH_PARSE_OK;
+	}
+    }
+
+  /* ARCH name not found in list.  */
+  return AARCH_PARSE_INVALID_ARG;
+}
+
+/* Parse the TO_PARSE string and put the result tuning in RES_CPU and the
+   architecture flags in RES_FLAGS.  Return an aarch_parse_opt_result
+   describing the parse result.  If there is an error parsing, RES_CPU and
+   RES_FLAGS are left unchanged.
+   When the TO_PARSE string contains an invalid extension,
+   a copy of the string is created and stored to INVALID_EXTENSION.  */
+
+enum aarch_parse_opt_result
+aarch64_parse_cpu (const char *to_parse, aarch64_cpu *res_cpu,
+		   aarch64_feature_flags *res_flags,
+		   std::string *invalid_extension)
+{
+  const char *ext;
+  const struct processor_info *cpu;
+  size_t len;
+
+  ext = strchr (to_parse, '+');
+
+  if (ext != NULL)
+    len = ext - to_parse;
+  else
+    len = strlen (to_parse);
+
+  if (len == 0)
+    return AARCH_PARSE_MISSING_ARG;
+
+
+  /* Loop through the list of supported CPUs to find a match.  */
+  for (cpu = all_cores; cpu->name != NULL; cpu++)
+    {
+      if (strlen (cpu->name) == len && strncmp (cpu->name, to_parse, len) == 0)
+	{
+	  auto isa_flags = cpu->flags;
+
+	  if (ext != NULL)
+	    {
+	      /* TO_PARSE string contains at least one extension.  */
+	      enum aarch_parse_opt_result ext_res
+		= aarch64_parse_extension (ext, &isa_flags, invalid_extension);
+
+	      if (ext_res != AARCH_PARSE_OK)
+		return ext_res;
+	    }
+	  /* Extension parsing was successfull.  Confirm the result
+	     cpu and ISA flags.  */
+	  *res_cpu = cpu->processor;
+	  *res_flags = isa_flags;
+	  return AARCH_PARSE_OK;
+	}
+    }
+
+  /* CPU name not found in list.  */
+  return AARCH_PARSE_INVALID_ARG;
 }
 
+/* Parse the TO_PARSE string and put the cpu it selects into RES_CPU.
+   Return an aarch_parse_opt_result describing the parse result.
+   If the parsing fails then RES_CPU does not change.  */
+
+enum aarch_parse_opt_result
+aarch64_parse_tune (const char *to_parse, aarch64_cpu *res_cpu)
+{
+  const struct processor_info *cpu;
+
+  /* Loop through the list of supported CPUs to find a match.  */
+  for (cpu = all_cores; cpu->name != NULL; cpu++)
+    {
+      if (strcmp (cpu->name, to_parse) == 0)
+	{
+	  *res_cpu = cpu->processor;
+	  return AARCH_PARSE_OK;
+	}
+    }
+
+  /* CPU name not found in list.  */
+  return AARCH_PARSE_INVALID_ARG;
+}
+
+
+/* Validate a command-line -march option.  Parse the arch and extensions
+   (if any) specified in STR and throw errors if appropriate.  Put the
+   results, if they are valid, in RES_ARCH and RES_FLAGS.  Return whether the
+   option is valid.  */
+
+bool
+aarch64_validate_march (const char *str, aarch64_arch *res_arch,
+			aarch64_feature_flags *res_flags)
+{
+  std::string invalid_extension;
+  enum aarch_parse_opt_result parse_res
+    = aarch64_parse_arch (str, res_arch, res_flags, &invalid_extension);
+
+  if (parse_res == AARCH_PARSE_OK)
+    return true;
+
+  switch (parse_res)
+    {
+      case AARCH_PARSE_MISSING_ARG:
+	error ("missing arch name in %<-march=%s%>", str);
+	break;
+      case AARCH_PARSE_INVALID_ARG:
+	{
+	  error ("unknown value %qs for %<-march%>", str);
+	  aarch64_print_hint_for_arch (str);
+	  /* A common user error is confusing -march and -mcpu.
+	     If the -march string matches a known CPU suggest -mcpu.  */
+	  aarch64_cpu temp_cpu;
+	  aarch64_feature_flags temp_flags;
+	  parse_res = aarch64_parse_cpu (str, &temp_cpu, &temp_flags,
+					 &invalid_extension);
+	  if (parse_res == AARCH_PARSE_OK)
+	    inform (input_location, "did you mean %<-mcpu=%s%>?", str);
+	  break;
+	}
+      case AARCH_PARSE_INVALID_FEATURE:
+	error ("invalid feature modifier %qs in %<-march=%s%>",
+	       invalid_extension.c_str (), str);
+	aarch64_print_hint_for_extensions (invalid_extension.c_str ());
+	break;
+      default:
+	gcc_unreachable ();
+    }
+
+  return false;
+}
+
+/* Validate a command-line -mcpu option.  Parse the cpu and extensions (if any)
+   specified in STR and throw errors if appropriate.  Put the results if
+   they are valid in RES_CPU and RES_FLAGS.  Return whether the option is
+   valid.  */
+
+bool
+aarch64_validate_mcpu (const char *str, aarch64_cpu *res_cpu,
+		       aarch64_feature_flags *res_flags)
+{
+  std::string invalid_extension;
+  enum aarch_parse_opt_result parse_res
+    = aarch64_parse_cpu (str, res_cpu, res_flags, &invalid_extension);
+
+  if (parse_res == AARCH_PARSE_OK)
+    return true;
+
+  switch (parse_res)
+    {
+      case AARCH_PARSE_MISSING_ARG:
+	error ("missing cpu name in %<-mcpu=%s%>", str);
+	break;
+      case AARCH_PARSE_INVALID_ARG:
+	{
+	  error ("unknown value %qs for %<-mcpu%>", str);
+	  aarch64_print_hint_for_core (str);
+	  /* A common user error is confusing -march and -mcpu.
+	     If the -mcpu string matches a known architecture then suggest
+	     -march=.  */
+	  aarch64_arch temp_arch;
+	  aarch64_feature_flags temp_flags;
+	  parse_res = aarch64_parse_arch (str, &temp_arch, &temp_flags,
+					  &invalid_extension);
+	  if (parse_res == AARCH_PARSE_OK)
+	    inform (input_location, "did you mean %<-march=%s%>?", str);
+	  break;
+	}
+      case AARCH_PARSE_INVALID_FEATURE:
+	error ("invalid feature modifier %qs in %<-mcpu=%s%>",
+	       invalid_extension.c_str (), str);
+	aarch64_print_hint_for_extensions (invalid_extension.c_str ());
+	break;
+      default:
+	gcc_unreachable ();
+    }
+
+  return false;
+}
+
+/* Validate a command-line -mtune option.  Parse the cpu
+   specified in STR and throw errors if appropriate.  Put the
+   result, if it is valid, in RES_CPU.  Return whether the option is
+   valid.  */
+
+bool
+aarch64_validate_mtune (const char *str, aarch64_cpu *res_cpu)
+{
+  enum aarch_parse_opt_result parse_res
+    = aarch64_parse_tune (str, res_cpu);
+
+  if (parse_res == AARCH_PARSE_OK)
+    return true;
+
+  switch (parse_res)
+    {
+      case AARCH_PARSE_MISSING_ARG:
+	error ("missing cpu name in %<-mtune=%s%>", str);
+	break;
+      case AARCH_PARSE_INVALID_ARG:
+	error ("unknown value %qs for %<-mtune%>", str);
+	aarch64_print_hint_for_core (str);
+	break;
+      default:
+	gcc_unreachable ();
+    }
+  return false;
+}
+
+
 /* Return a string representation of ISA_FLAGS.  DEFAULT_ARCH_FLAGS
    gives the default set of flags which are implied by whatever -march
    we'd put out.  Our job is to figure out the minimal set of "+" and
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index fa7bc8029be04f6530d2aee2ead4d754ba3b2550..4114fc9b3b7645b8781257f6f775ddfe7e8c339e 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -1190,11 +1190,27 @@  void aarch64_set_asm_isa_flags (aarch64_feature_flags);
 void aarch64_set_asm_isa_flags (gcc_options *, aarch64_feature_flags);
 bool aarch64_handle_option (struct gcc_options *, struct gcc_options *,
 			     const struct cl_decoded_option *, location_t);
-const char *aarch64_rewrite_selected_cpu (const char *name);
+void aarch64_print_hint_for_extensions (const char *);
+void aarch64_print_hint_for_arch (const char *);
+void aarch64_print_hint_for_core (const char *);
 enum aarch_parse_opt_result aarch64_parse_extension (const char *,
                                                      aarch64_feature_flags *,
                                                      std::string *);
-void aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates);
+enum aarch_parse_opt_result aarch64_parse_arch (const char *,
+						aarch64_arch *,
+						aarch64_feature_flags *,
+						std::string *);
+enum aarch_parse_opt_result aarch64_parse_cpu (const char *,
+					       aarch64_cpu *,
+					       aarch64_feature_flags *,
+					       std::string *);
+enum aarch_parse_opt_result aarch64_parse_tune (const char *, aarch64_cpu *);
+bool aarch64_validate_march (const char *, aarch64_arch *,
+			     aarch64_feature_flags *);
+bool aarch64_validate_mcpu (const char *, aarch64_cpu *,
+			    aarch64_feature_flags *);
+bool aarch64_validate_mtune (const char *, aarch64_cpu *);
+const char *aarch64_rewrite_selected_cpu (const char *name);
 std::string aarch64_get_extension_string_for_isa_flags (aarch64_feature_flags,
 							aarch64_feature_flags);
 
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index f33034cbb205eb52b5ee5965b8b972cedf6f4927..75ba66a979c979fd01948b0a2066a15371df9bfa 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -18217,140 +18217,6 @@  better_main_loop_than_p (const vector_costs *uncast_other) const
 
 static void initialize_aarch64_code_model (struct gcc_options *);
 
-/* Parse the TO_PARSE string and put the architecture that it
-   selects into RES_ARCH and the architectural features into RES_FLAGS.
-   Return an aarch_parse_opt_result describing the parse result.
-   If there is an error parsing, RES_ARCH and RES_FLAGS are left unchanged.
-   When the TO_PARSE string contains an invalid extension,
-   a copy of the string is created and stored to INVALID_EXTENSION.  */
-
-static enum aarch_parse_opt_result
-aarch64_parse_arch (const char *to_parse, aarch64_arch *res_arch,
-		    aarch64_feature_flags *res_flags,
-		    std::string *invalid_extension)
-{
-  const char *ext;
-  const struct processor *arch;
-  size_t len;
-
-  ext = strchr (to_parse, '+');
-
-  if (ext != NULL)
-    len = ext - to_parse;
-  else
-    len = strlen (to_parse);
-
-  if (len == 0)
-    return AARCH_PARSE_MISSING_ARG;
-
-
-  /* Loop through the list of supported ARCHes to find a match.  */
-  for (arch = all_architectures; arch->name != NULL; arch++)
-    {
-      if (strlen (arch->name) == len
-	  && strncmp (arch->name, to_parse, len) == 0)
-	{
-	  auto isa_flags = arch->flags;
-
-	  if (ext != NULL)
-	    {
-	      /* TO_PARSE string contains at least one extension.  */
-	      enum aarch_parse_opt_result ext_res
-		= aarch64_parse_extension (ext, &isa_flags, invalid_extension);
-
-	      if (ext_res != AARCH_PARSE_OK)
-		return ext_res;
-	    }
-	  /* Extension parsing was successful.  Confirm the result
-	     arch and ISA flags.  */
-	  *res_arch = arch->arch;
-	  *res_flags = isa_flags;
-	  return AARCH_PARSE_OK;
-	}
-    }
-
-  /* ARCH name not found in list.  */
-  return AARCH_PARSE_INVALID_ARG;
-}
-
-/* Parse the TO_PARSE string and put the result tuning in RES_CPU and the
-   architecture flags in RES_FLAGS.  Return an aarch_parse_opt_result
-   describing the parse result.  If there is an error parsing, RES_CPU and
-   RES_FLAGS are left unchanged.
-   When the TO_PARSE string contains an invalid extension,
-   a copy of the string is created and stored to INVALID_EXTENSION.  */
-
-static enum aarch_parse_opt_result
-aarch64_parse_cpu (const char *to_parse, aarch64_cpu *res_cpu,
-		   aarch64_feature_flags *res_flags,
-		   std::string *invalid_extension)
-{
-  const char *ext;
-  const struct processor *cpu;
-  size_t len;
-
-  ext = strchr (to_parse, '+');
-
-  if (ext != NULL)
-    len = ext - to_parse;
-  else
-    len = strlen (to_parse);
-
-  if (len == 0)
-    return AARCH_PARSE_MISSING_ARG;
-
-
-  /* Loop through the list of supported CPUs to find a match.  */
-  for (cpu = all_cores; cpu->name != NULL; cpu++)
-    {
-      if (strlen (cpu->name) == len && strncmp (cpu->name, to_parse, len) == 0)
-	{
-	  auto isa_flags = cpu->flags;
-
-	  if (ext != NULL)
-	    {
-	      /* TO_PARSE string contains at least one extension.  */
-	      enum aarch_parse_opt_result ext_res
-		= aarch64_parse_extension (ext, &isa_flags, invalid_extension);
-
-	      if (ext_res != AARCH_PARSE_OK)
-		return ext_res;
-	    }
-	  /* Extension parsing was successfull.  Confirm the result
-	     cpu and ISA flags.  */
-	  *res_cpu = cpu->ident;
-	  *res_flags = isa_flags;
-	  return AARCH_PARSE_OK;
-	}
-    }
-
-  /* CPU name not found in list.  */
-  return AARCH_PARSE_INVALID_ARG;
-}
-
-/* Parse the TO_PARSE string and put the cpu it selects into RES_CPU.
-   Return an aarch_parse_opt_result describing the parse result.
-   If the parsing fails then RES_CPU does not change.  */
-
-static enum aarch_parse_opt_result
-aarch64_parse_tune (const char *to_parse, aarch64_cpu *res_cpu)
-{
-  const struct processor *cpu;
-
-  /* Loop through the list of supported CPUs to find a match.  */
-  for (cpu = all_cores; cpu->name != NULL; cpu++)
-    {
-      if (strcmp (cpu->name, to_parse) == 0)
-	{
-	  *res_cpu = cpu->ident;
-	  return AARCH_PARSE_OK;
-	}
-    }
-
-  /* CPU name not found in list.  */
-  return AARCH_PARSE_INVALID_ARG;
-}
-
 /* Parse TOKEN, which has length LENGTH to see if it is an option
    described in FLAG.  If it is, return the index bit for that fusion type.
    If not, error (printing OPTION_NAME) and return zero.  */
@@ -18884,123 +18750,6 @@  aarch64_override_options_internal (struct gcc_options *opts)
   aarch64_override_options_after_change_1 (opts);
 }
 
-/* Print a hint with a suggestion for a core name that most closely resembles
-   what the user passed in STR.  */
-
-inline static void
-aarch64_print_hint_for_core (const char *str)
-{
-  auto_vec<const char *> candidates;
-  const struct processor *entry = all_cores;
-  for (; entry->name != NULL; entry++)
-    candidates.safe_push (entry->name);
-
-  char *s;
-  const char *hint = candidates_list_and_hint (str, 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);
-}
-
-/* Print a hint with a suggestion for an architecture name that most closely
-   resembles what the user passed in STR.  */
-
-inline static void
-aarch64_print_hint_for_arch (const char *str)
-{
-  auto_vec<const char *> candidates;
-  const struct processor *entry = all_architectures;
-  for (; entry->name != NULL; entry++)
-    candidates.safe_push (entry->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 (str, 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);
-}
-
-
-/* Print a hint with a suggestion for an extension name
-   that most closely resembles what the user passed in STR.  */
-
-void
-aarch64_print_hint_for_extensions (const char *str)
-{
-  auto_vec<const char *> candidates;
-  aarch64_get_all_extension_candidates (&candidates);
-  char *s;
-  const char *hint = candidates_list_and_hint (str, 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);
-}
-
-/* Validate a command-line -mcpu option.  Parse the cpu and extensions (if any)
-   specified in STR and throw errors if appropriate.  Put the results if
-   they are valid in RES_CPU and RES_FLAGS.  Return whether the option is
-   valid.  */
-
-static bool
-aarch64_validate_mcpu (const char *str, aarch64_cpu *res_cpu,
-		       aarch64_feature_flags *res_flags)
-{
-  std::string invalid_extension;
-  enum aarch_parse_opt_result parse_res
-    = aarch64_parse_cpu (str, res_cpu, res_flags, &invalid_extension);
-
-  if (parse_res == AARCH_PARSE_OK)
-    return true;
-
-  switch (parse_res)
-    {
-      case AARCH_PARSE_MISSING_ARG:
-	error ("missing cpu name in %<-mcpu=%s%>", str);
-	break;
-      case AARCH_PARSE_INVALID_ARG:
-	{
-	  error ("unknown value %qs for %<-mcpu%>", str);
-	  aarch64_print_hint_for_core (str);
-	  /* A common user error is confusing -march and -mcpu.
-	     If the -mcpu string matches a known architecture then suggest
-	     -march=.  */
-	  aarch64_arch temp_arch;
-	  aarch64_feature_flags temp_flags;
-	  parse_res = aarch64_parse_arch (str, &temp_arch, &temp_flags,
-					  &invalid_extension);
-	  if (parse_res == AARCH_PARSE_OK)
-	    inform (input_location, "did you mean %<-march=%s%>?", str);
-	  break;
-	}
-      case AARCH_PARSE_INVALID_FEATURE:
-	error ("invalid feature modifier %qs in %<-mcpu=%s%>",
-	       invalid_extension.c_str (), str);
-	aarch64_print_hint_for_extensions (invalid_extension.c_str ());
-	break;
-      default:
-	gcc_unreachable ();
-    }
-
-  return false;
-}
-
 /* Straight line speculation indicators.  */
 enum aarch64_sls_hardening_type
 {
@@ -19074,82 +18823,6 @@  aarch64_validate_sls_mitigation (const char *const_str)
   free (str_root);
 }
 
-/* Validate a command-line -march option.  Parse the arch and extensions
-   (if any) specified in STR and throw errors if appropriate.  Put the
-   results, if they are valid, in RES_ARCH and RES_FLAGS.  Return whether the
-   option is valid.  */
-
-static bool
-aarch64_validate_march (const char *str, aarch64_arch *res_arch,
-			aarch64_feature_flags *res_flags)
-{
-  std::string invalid_extension;
-  enum aarch_parse_opt_result parse_res
-    = aarch64_parse_arch (str, res_arch, res_flags, &invalid_extension);
-
-  if (parse_res == AARCH_PARSE_OK)
-    return true;
-
-  switch (parse_res)
-    {
-      case AARCH_PARSE_MISSING_ARG:
-	error ("missing arch name in %<-march=%s%>", str);
-	break;
-      case AARCH_PARSE_INVALID_ARG:
-	{
-	  error ("unknown value %qs for %<-march%>", str);
-	  aarch64_print_hint_for_arch (str);
-	  /* A common user error is confusing -march and -mcpu.
-	     If the -march string matches a known CPU suggest -mcpu.  */
-	  aarch64_cpu temp_cpu;
-	  aarch64_feature_flags temp_flags;
-	  parse_res = aarch64_parse_cpu (str, &temp_cpu, &temp_flags,
-					 &invalid_extension);
-	  if (parse_res == AARCH_PARSE_OK)
-	    inform (input_location, "did you mean %<-mcpu=%s%>?", str);
-	  break;
-	}
-      case AARCH_PARSE_INVALID_FEATURE:
-	error ("invalid feature modifier %qs in %<-march=%s%>",
-	       invalid_extension.c_str (), str);
-	aarch64_print_hint_for_extensions (invalid_extension.c_str ());
-	break;
-      default:
-	gcc_unreachable ();
-    }
-
-  return false;
-}
-
-/* Validate a command-line -mtune option.  Parse the cpu
-   specified in STR and throw errors if appropriate.  Put the
-   result, if it is valid, in RES_CPU.  Return whether the option is
-   valid.  */
-
-static bool
-aarch64_validate_mtune (const char *str, aarch64_cpu *res_cpu)
-{
-  enum aarch_parse_opt_result parse_res
-    = aarch64_parse_tune (str, res_cpu);
-
-  if (parse_res == AARCH_PARSE_OK)
-    return true;
-
-  switch (parse_res)
-    {
-      case AARCH_PARSE_MISSING_ARG:
-	error ("missing cpu name in %<-mtune=%s%>", str);
-	break;
-      case AARCH_PARSE_INVALID_ARG:
-	error ("unknown value %qs for %<-mtune%>", str);
-	aarch64_print_hint_for_core (str);
-	break;
-      default:
-	gcc_unreachable ();
-    }
-  return false;
-}
-
 /* Return the VG value associated with -msve-vector-bits= value VALUE.  */
 
 static poly_uint16