Skip to content

Commit ecb4565

Browse files
aarch64: Move arch/cpu parsing to aarch64-common.cc
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_candidates): Move from aarch64.cc. (aarch64_print_hint_for_extensions): Ditto. (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_candidates): 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.
1 parent 5c5b6a9 commit ecb4565

File tree

3 files changed

+346
-328
lines changed

3 files changed

+346
-328
lines changed

gcc/common/config/aarch64/aarch64-common.cc

Lines changed: 328 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,78 @@ static constexpr aarch64_processor_info all_cores[] =
205205
};
206206

207207

208+
/* Print a list of CANDIDATES for an argument, and try to suggest a specific
209+
close match. */
210+
211+
inline static void
212+
aarch64_print_hint_candidates (const char *str,
213+
const auto_vec<const char*> & candidates)
214+
{
215+
char *s;
216+
const char *hint = candidates_list_and_hint (str, s, candidates);
217+
if (hint)
218+
inform (input_location, "valid arguments are: %s;"
219+
" did you mean %qs?", s, hint);
220+
else
221+
inform (input_location, "valid arguments are: %s", s);
222+
223+
XDELETEVEC (s);
224+
}
225+
226+
/* Append all architecture extension candidates to the CANDIDATES vector. */
227+
228+
void
229+
aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates)
230+
{
231+
const struct aarch64_extension_info *opt;
232+
for (opt = all_extensions; opt->name != NULL; opt++)
233+
candidates->safe_push (opt->name);
234+
}
235+
236+
/* Print a hint with a suggestion for an extension name
237+
that most closely resembles what the user passed in STR. */
238+
239+
void
240+
aarch64_print_hint_for_extensions (const char *str)
241+
{
242+
auto_vec<const char *> candidates;
243+
aarch64_get_all_extension_candidates (&candidates);
244+
aarch64_print_hint_candidates (str, candidates);
245+
}
246+
247+
/* Print a hint with a suggestion for an architecture name that most closely
248+
resembles what the user passed in STR. */
249+
250+
void
251+
aarch64_print_hint_for_arch (const char *str)
252+
{
253+
auto_vec<const char *> candidates;
254+
const struct aarch64_arch_info *entry = all_architectures;
255+
for (; entry->name != NULL; entry++)
256+
candidates.safe_push (entry->name);
257+
258+
#ifdef HAVE_LOCAL_CPU_DETECT
259+
/* Add also "native" as possible value. */
260+
candidates.safe_push ("native");
261+
#endif
262+
263+
aarch64_print_hint_candidates (str, candidates);
264+
}
265+
266+
/* Print a hint with a suggestion for a core name that most closely resembles
267+
what the user passed in STR. */
268+
269+
void
270+
aarch64_print_hint_for_core (const char *str)
271+
{
272+
auto_vec<const char *> candidates;
273+
const struct aarch64_processor_info *entry = all_cores;
274+
for (; entry->name != NULL; entry++)
275+
candidates.safe_push (entry->name);
276+
aarch64_print_hint_candidates (str, candidates);
277+
}
278+
279+
208280
/* Parse the architecture extension string STR and update ISA_FLAGS
209281
with the architecture features turned on or off. Return a
210282
aarch_parse_opt_result describing the result.
@@ -275,16 +347,266 @@ aarch64_parse_extension (const char *str, aarch64_feature_flags *isa_flags,
275347
return AARCH_PARSE_OK;
276348
}
277349

278-
/* Append all architecture extension candidates to the CANDIDATES vector. */
350+
/* Parse the TO_PARSE string and put the architecture that it
351+
selects into RES_ARCH and the architectural features into RES_FLAGS.
352+
Return an aarch_parse_opt_result describing the parse result.
353+
If there is an error parsing, RES_ARCH and RES_FLAGS are left unchanged.
354+
When the TO_PARSE string contains an invalid extension,
355+
a copy of the string is created and stored to INVALID_EXTENSION. */
279356

280-
void
281-
aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates)
357+
enum aarch_parse_opt_result
358+
aarch64_parse_arch (const char *to_parse, aarch64_arch *res_arch,
359+
aarch64_feature_flags *res_flags,
360+
std::string *invalid_extension)
282361
{
283-
const struct aarch64_extension_info *opt;
284-
for (opt = all_extensions; opt->name != NULL; opt++)
285-
candidates->safe_push (opt->name);
362+
const char *ext;
363+
const struct aarch64_arch_info *arch;
364+
size_t len;
365+
366+
ext = strchr (to_parse, '+');
367+
368+
if (ext != NULL)
369+
len = ext - to_parse;
370+
else
371+
len = strlen (to_parse);
372+
373+
if (len == 0)
374+
return AARCH_PARSE_MISSING_ARG;
375+
376+
377+
/* Loop through the list of supported ARCHes to find a match. */
378+
for (arch = all_architectures; arch->name != NULL; arch++)
379+
{
380+
if (strlen (arch->name) == len
381+
&& strncmp (arch->name, to_parse, len) == 0)
382+
{
383+
auto isa_flags = arch->flags;
384+
385+
if (ext != NULL)
386+
{
387+
/* TO_PARSE string contains at least one extension. */
388+
enum aarch_parse_opt_result ext_res
389+
= aarch64_parse_extension (ext, &isa_flags, invalid_extension);
390+
391+
if (ext_res != AARCH_PARSE_OK)
392+
return ext_res;
393+
}
394+
/* Extension parsing was successful. Confirm the result
395+
arch and ISA flags. */
396+
*res_arch = arch->arch;
397+
*res_flags = isa_flags;
398+
return AARCH_PARSE_OK;
399+
}
400+
}
401+
402+
/* ARCH name not found in list. */
403+
return AARCH_PARSE_INVALID_ARG;
404+
}
405+
406+
/* Parse the TO_PARSE string and put the result tuning in RES_CPU and the
407+
architecture flags in RES_FLAGS. Return an aarch_parse_opt_result
408+
describing the parse result. If there is an error parsing, RES_CPU and
409+
RES_FLAGS are left unchanged.
410+
When the TO_PARSE string contains an invalid extension,
411+
a copy of the string is created and stored to INVALID_EXTENSION. */
412+
413+
enum aarch_parse_opt_result
414+
aarch64_parse_cpu (const char *to_parse, aarch64_cpu *res_cpu,
415+
aarch64_feature_flags *res_flags,
416+
std::string *invalid_extension)
417+
{
418+
const char *ext;
419+
const struct aarch64_processor_info *cpu;
420+
size_t len;
421+
422+
ext = strchr (to_parse, '+');
423+
424+
if (ext != NULL)
425+
len = ext - to_parse;
426+
else
427+
len = strlen (to_parse);
428+
429+
if (len == 0)
430+
return AARCH_PARSE_MISSING_ARG;
431+
432+
433+
/* Loop through the list of supported CPUs to find a match. */
434+
for (cpu = all_cores; cpu->name != NULL; cpu++)
435+
{
436+
if (strlen (cpu->name) == len && strncmp (cpu->name, to_parse, len) == 0)
437+
{
438+
auto isa_flags = cpu->flags;
439+
440+
if (ext != NULL)
441+
{
442+
/* TO_PARSE string contains at least one extension. */
443+
enum aarch_parse_opt_result ext_res
444+
= aarch64_parse_extension (ext, &isa_flags, invalid_extension);
445+
446+
if (ext_res != AARCH_PARSE_OK)
447+
return ext_res;
448+
}
449+
/* Extension parsing was successfull. Confirm the result
450+
cpu and ISA flags. */
451+
*res_cpu = cpu->processor;
452+
*res_flags = isa_flags;
453+
return AARCH_PARSE_OK;
454+
}
455+
}
456+
457+
/* CPU name not found in list. */
458+
return AARCH_PARSE_INVALID_ARG;
286459
}
287460

461+
/* Parse the TO_PARSE string and put the cpu it selects into RES_CPU.
462+
Return an aarch_parse_opt_result describing the parse result.
463+
If the parsing fails then RES_CPU does not change. */
464+
465+
enum aarch_parse_opt_result
466+
aarch64_parse_tune (const char *to_parse, aarch64_cpu *res_cpu)
467+
{
468+
const struct aarch64_processor_info *cpu;
469+
470+
/* Loop through the list of supported CPUs to find a match. */
471+
for (cpu = all_cores; cpu->name != NULL; cpu++)
472+
{
473+
if (strcmp (cpu->name, to_parse) == 0)
474+
{
475+
*res_cpu = cpu->processor;
476+
return AARCH_PARSE_OK;
477+
}
478+
}
479+
480+
/* CPU name not found in list. */
481+
return AARCH_PARSE_INVALID_ARG;
482+
}
483+
484+
485+
/* Validate a command-line -march option. Parse the arch and extensions
486+
(if any) specified in STR and throw errors if appropriate. Put the
487+
results, if they are valid, in RES_ARCH and RES_FLAGS. Return whether the
488+
option is valid. */
489+
490+
bool
491+
aarch64_validate_march (const char *str, aarch64_arch *res_arch,
492+
aarch64_feature_flags *res_flags)
493+
{
494+
std::string invalid_extension;
495+
enum aarch_parse_opt_result parse_res
496+
= aarch64_parse_arch (str, res_arch, res_flags, &invalid_extension);
497+
498+
if (parse_res == AARCH_PARSE_OK)
499+
return true;
500+
501+
switch (parse_res)
502+
{
503+
case AARCH_PARSE_MISSING_ARG:
504+
error ("missing arch name in %<-march=%s%>", str);
505+
break;
506+
case AARCH_PARSE_INVALID_ARG:
507+
{
508+
error ("unknown value %qs for %<-march%>", str);
509+
aarch64_print_hint_for_arch (str);
510+
/* A common user error is confusing -march and -mcpu.
511+
If the -march string matches a known CPU suggest -mcpu. */
512+
aarch64_cpu temp_cpu;
513+
aarch64_feature_flags temp_flags;
514+
parse_res = aarch64_parse_cpu (str, &temp_cpu, &temp_flags,
515+
&invalid_extension);
516+
if (parse_res == AARCH_PARSE_OK)
517+
inform (input_location, "did you mean %<-mcpu=%s%>?", str);
518+
break;
519+
}
520+
case AARCH_PARSE_INVALID_FEATURE:
521+
error ("invalid feature modifier %qs in %<-march=%s%>",
522+
invalid_extension.c_str (), str);
523+
aarch64_print_hint_for_extensions (invalid_extension.c_str ());
524+
break;
525+
default:
526+
gcc_unreachable ();
527+
}
528+
529+
return false;
530+
}
531+
532+
/* Validate a command-line -mcpu option. Parse the cpu and extensions (if any)
533+
specified in STR and throw errors if appropriate. Put the results if
534+
they are valid in RES_CPU and RES_FLAGS. Return whether the option is
535+
valid. */
536+
537+
bool
538+
aarch64_validate_mcpu (const char *str, aarch64_cpu *res_cpu,
539+
aarch64_feature_flags *res_flags)
540+
{
541+
std::string invalid_extension;
542+
enum aarch_parse_opt_result parse_res
543+
= aarch64_parse_cpu (str, res_cpu, res_flags, &invalid_extension);
544+
545+
if (parse_res == AARCH_PARSE_OK)
546+
return true;
547+
548+
switch (parse_res)
549+
{
550+
case AARCH_PARSE_MISSING_ARG:
551+
error ("missing cpu name in %<-mcpu=%s%>", str);
552+
break;
553+
case AARCH_PARSE_INVALID_ARG:
554+
{
555+
error ("unknown value %qs for %<-mcpu%>", str);
556+
aarch64_print_hint_for_core (str);
557+
/* A common user error is confusing -march and -mcpu.
558+
If the -mcpu string matches a known architecture then suggest
559+
-march=. */
560+
aarch64_arch temp_arch;
561+
aarch64_feature_flags temp_flags;
562+
parse_res = aarch64_parse_arch (str, &temp_arch, &temp_flags,
563+
&invalid_extension);
564+
if (parse_res == AARCH_PARSE_OK)
565+
inform (input_location, "did you mean %<-march=%s%>?", str);
566+
break;
567+
}
568+
case AARCH_PARSE_INVALID_FEATURE:
569+
error ("invalid feature modifier %qs in %<-mcpu=%s%>",
570+
invalid_extension.c_str (), str);
571+
aarch64_print_hint_for_extensions (invalid_extension.c_str ());
572+
break;
573+
default:
574+
gcc_unreachable ();
575+
}
576+
577+
return false;
578+
}
579+
580+
/* Validate a command-line -mtune option. Parse the cpu
581+
specified in STR and throw errors if appropriate. Put the
582+
result, if it is valid, in RES_CPU. Return whether the option is
583+
valid. */
584+
585+
bool
586+
aarch64_validate_mtune (const char *str, aarch64_cpu *res_cpu)
587+
{
588+
enum aarch_parse_opt_result parse_res
589+
= aarch64_parse_tune (str, res_cpu);
590+
591+
if (parse_res == AARCH_PARSE_OK)
592+
return true;
593+
594+
switch (parse_res)
595+
{
596+
case AARCH_PARSE_MISSING_ARG:
597+
error ("missing cpu name in %<-mtune=%s%>", str);
598+
break;
599+
case AARCH_PARSE_INVALID_ARG:
600+
error ("unknown value %qs for %<-mtune%>", str);
601+
aarch64_print_hint_for_core (str);
602+
break;
603+
default:
604+
gcc_unreachable ();
605+
}
606+
return false;
607+
}
608+
609+
288610
/* Return a string representation of ISA_FLAGS. DEFAULT_ARCH_FLAGS
289611
gives the default set of flags which are implied by whatever -march
290612
we'd put out. Our job is to figure out the minimal set of "+" and

gcc/config/aarch64/aarch64-protos.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,11 +1190,27 @@ void aarch64_set_asm_isa_flags (aarch64_feature_flags);
11901190
void aarch64_set_asm_isa_flags (gcc_options *, aarch64_feature_flags);
11911191
bool aarch64_handle_option (struct gcc_options *, struct gcc_options *,
11921192
const struct cl_decoded_option *, location_t);
1193-
const char *aarch64_rewrite_selected_cpu (const char *name);
1193+
void aarch64_print_hint_for_extensions (const char *);
1194+
void aarch64_print_hint_for_arch (const char *);
1195+
void aarch64_print_hint_for_core (const char *);
11941196
enum aarch_parse_opt_result aarch64_parse_extension (const char *,
11951197
aarch64_feature_flags *,
11961198
std::string *);
1197-
void aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates);
1199+
enum aarch_parse_opt_result aarch64_parse_arch (const char *,
1200+
aarch64_arch *,
1201+
aarch64_feature_flags *,
1202+
std::string *);
1203+
enum aarch_parse_opt_result aarch64_parse_cpu (const char *,
1204+
aarch64_cpu *,
1205+
aarch64_feature_flags *,
1206+
std::string *);
1207+
enum aarch_parse_opt_result aarch64_parse_tune (const char *, aarch64_cpu *);
1208+
bool aarch64_validate_march (const char *, aarch64_arch *,
1209+
aarch64_feature_flags *);
1210+
bool aarch64_validate_mcpu (const char *, aarch64_cpu *,
1211+
aarch64_feature_flags *);
1212+
bool aarch64_validate_mtune (const char *, aarch64_cpu *);
1213+
const char *aarch64_rewrite_selected_cpu (const char *name);
11981214
std::string aarch64_get_extension_string_for_isa_flags (aarch64_feature_flags,
11991215
aarch64_feature_flags);
12001216

0 commit comments

Comments
 (0)