diff options
author | rearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-06-16 21:03:17 +0000 |
---|---|---|
committer | rearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-06-16 21:03:17 +0000 |
commit | 8498ba661df3aece8fad0cc6f23d1679c7c674bf (patch) | |
tree | 29d7712b53a17619243e53df8b57ccdbdb6a1622 /gcc/common | |
parent | ab6a47e44c73e82524f480ef6bd0a7e0fff43e69 (diff) | |
download | gcc-8498ba661df3aece8fad0cc6f23d1679c7c674bf.tar.gz |
[arm] Move cpu and architecture option name parsing
This patch has no functional change. The code used for parsing -mcpu,
-mtune and -march options is simply moved from arm.c arm-common.c.
The list of FPU options is also moved. Subsequent patches will make
use of this within the driver.
Some small adjustments are needed as a consequence of moving the
definitions of the data objects to another object file, in that we
no-longer have direct access to the size of the object.
* common/config/arm/arm-common.c (arm_initialize_isa): Moved here from
config/arm/arm.c.
(arm_print_hint_for_cpu_option): Likewise.
(arm_print_hint_for_arch_option): Likewise.
(arm_parse_cpu_option_name): Likewise.
(arm_parse_arch_option_name): Likewise.
* config/arm/arm.c (arm_identify_fpu_from_isa): Use the computed number
of entries in the all_fpus list.
* config/arm/arm-protos.h (all_architectures, all_cores): Declare.
(arm_parse_cpu_option_name): Declare.
(arm_parse_arch_option_name): Declare.
(arm_parse_option_features): Declare.
(arm_intialize_isa): Declare.
* config/arm/parsecpu.awk (gen_data): Move CPU and architecture
data tables to ...
(gen_comm_data): ... here. Make definitions non-static.
* config/arm/arm-cpu-data.h: Regenerated.
* config/arm/arm-cpu-cdata.h: Regenerated.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@249287 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/common')
-rw-r--r-- | gcc/common/config/arm/arm-common.c | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/gcc/common/config/arm/arm-common.c b/gcc/common/config/arm/arm-common.c index fd0c6165541..f44ba1f92b2 100644 --- a/gcc/common/config/arm/arm-common.c +++ b/gcc/common/config/arm/arm-common.c @@ -27,6 +27,8 @@ #include "common/common-target-def.h" #include "opts.h" #include "flags.h" +#include "sbitmap.h" +#include "diagnostic.h" /* Set default optimization options. */ static const struct default_options arm_option_optimization_table[] = @@ -187,6 +189,194 @@ arm_target_thumb_only (int argc, const char **argv) return NULL; } +/* 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); + 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. */ +const cpu_option * +arm_parse_cpu_option_name (const cpu_option *list, const char *optname, + const char *target) +{ + 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; + } + + 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); + 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. */ +const arch_option * +arm_parse_arch_option_name (const arch_option *list, const char *optname, + const char *target) +{ + 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; + } + + error_at (input_location, "unrecognized %s target: %s", optname, target); + arm_print_hint_for_arch_option (target, list); + 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; + } +} + #undef ARM_CPU_NAME_LENGTH |