+2015-08-20 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * common/config/aarch64/aarch64-common.c
+ (AARCH64_CPU_NAME_LENGTH): Delete.
+ (aarch64_option_extension): New.
+ (all_extensions): Likewise.
+ (processor_name_to_arch): Likewise.
+ (arch_to_arch_name): Likewise.
+ (all_cores): New.
+ (all_architectures): Likewise.
+ (aarch64_get_extension_string_for_isa_flags): Likewise.
+ (aarch64_rewrite_selected_cpu): Change to rewrite CPU names to
+ architecture names.
+ * config/aarch64/aarch64-protos.h
+ (aarch64_get_extension_string_for_isa_flags): New.
+ * config/aarch64/aarch64.c (aarch64_print_extension): Delete.
+ (aarch64_option_print): Get the string to print from
+ aarch64_get_extension_string_for_isa_flags.
+ (aarch64_declare_function_name): Likewise.
+ * config/aarch64/aarch64.h (BIG_LITTLE_SPEC): Rename to...
+ (MCPU_TO_MARCH_SPEC): This.
+ (ASM_CPU_SPEC): Use it.
+ (BIG_LITTLE_SPEC_FUNCTIONS): Rename to...
+ (MCPU_TO_MARCH_SPEC_FUNCTIONS): ...This.
+ (EXTRA_SPEC_FUNCTIONS): Use it.
+
2015-08-20 Simon Dardis <simon.dardis@imgtec.com>
* config/mips/mips.c (mips_expand_block_move): Enable inline memcpy
#include "common/common-target-def.h"
#include "opts.h"
#include "flags.h"
-#include "errors.h"
+#include "diagnostic.h"
#ifdef TARGET_BIG_ENDIAN_DEFAULT
#undef TARGET_DEFAULT_TARGET_FLAGS
struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
-#define AARCH64_CPU_NAME_LENGTH 128
+/* An ISA extension in the co-processor and main instruction set space. */
+struct aarch64_option_extension
+{
+ const char *const name;
+ const unsigned long flags_on;
+ const unsigned long flags_off;
+};
+
+/* ISA extensions in AArch64. */
+static const struct aarch64_option_extension all_extensions[] =
+{
+#define AARCH64_OPT_EXTENSION(NAME, FLAGS_ON, FLAGS_OFF, FEATURE_STRING) \
+ {NAME, FLAGS_ON, FLAGS_OFF},
+#include "config/aarch64/aarch64-option-extensions.def"
+#undef AARCH64_OPT_EXTENSION
+ {NULL, 0, 0}
+};
+
+struct processor_name_to_arch
+{
+ const std::string processor_name;
+ const enum aarch64_arch arch;
+ const unsigned long flags;
+};
+
+struct arch_to_arch_name
+{
+ const enum aarch64_arch arch;
+ const std::string arch_name;
+};
+
+/* Map processor names to the architecture revision they implement and
+ the default set of architectural feature flags they support. */
+static const struct processor_name_to_arch all_cores[] =
+{
+#define AARCH64_CORE(NAME, X, IDENT, ARCH_IDENT, FLAGS, COSTS, IMP, PART) \
+ {NAME, AARCH64_ARCH_##ARCH_IDENT, FLAGS},
+#include "config/aarch64/aarch64-cores.def"
+#undef AARCH64_CORE
+ {"generic", AARCH64_ARCH_8A, AARCH64_FL_FOR_ARCH8},
+ {"", aarch64_no_arch, 0}
+};
+
+/* Map architecture revisions to their string representation. */
+static const struct arch_to_arch_name all_architectures[] =
+{
+#define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, ARCH, FLAGS) \
+ {AARCH64_ARCH_##ARCH_IDENT, NAME},
+#include "config/aarch64/aarch64-arches.def"
+#undef AARCH64_ARCH
+ {aarch64_no_arch, ""}
+};
+
+/* Return a string representation of ISA_FLAGS. */
+
+std::string
+aarch64_get_extension_string_for_isa_flags (unsigned long isa_flags)
+{
+ const struct aarch64_option_extension *opt = NULL;
+ std::string outstr = "";
+
+ for (opt = all_extensions; opt->name != NULL; opt++)
+ if ((isa_flags & opt->flags_on) == opt->flags_on)
+ {
+ outstr += "+";
+ outstr += opt->name;
+ }
+ return outstr;
+}
-/* Truncate NAME at the first '.' character seen up to the first '+'
- or return NAME unmodified. */
+/* Attempt to rewrite NAME, which has been passed on the command line
+ as a -mcpu option to an equivalent -march value. If we can do so,
+ return the new string, otherwise return an error. */
const char *
aarch64_rewrite_selected_cpu (const char *name)
{
- static char output_buf[AARCH64_CPU_NAME_LENGTH + 1] = {0};
- const char *bL_sep;
- const char *feats;
- size_t pref_size;
- size_t feat_size;
-
- bL_sep = strchr (name, '.');
- if (!bL_sep)
- return name;
+ std::string original_string (name);
+ std::string extensions;
+ std::string processor;
+ size_t extension_pos = original_string.find_first_of ('+');
- feats = strchr (name, '+');
- feat_size = feats ? strnlen (feats, AARCH64_CPU_NAME_LENGTH) : 0;
- pref_size = bL_sep - name;
+ /* Strip and save the extension string. */
+ if (extension_pos != std::string::npos)
+ {
+ processor = original_string.substr (0, extension_pos);
+ extensions = original_string.substr (extension_pos,
+ std::string::npos);
+ }
+ else
+ {
+ /* No extensions. */
+ processor = original_string;
+ }
- if ((feat_size + pref_size) > AARCH64_CPU_NAME_LENGTH)
- internal_error ("-mcpu string too large");
+ const struct processor_name_to_arch* p_to_a;
+ for (p_to_a = all_cores;
+ p_to_a->arch != aarch64_no_arch;
+ p_to_a++)
+ {
+ if (p_to_a->processor_name == processor)
+ break;
+ }
- strncpy (output_buf, name, pref_size);
- if (feats)
- strncpy (output_buf + pref_size, feats, feat_size);
+ const struct arch_to_arch_name* a_to_an;
+ for (a_to_an = all_architectures;
+ a_to_an->arch != aarch64_no_arch;
+ a_to_an++)
+ {
+ if (a_to_an->arch == p_to_a->arch)
+ break;
+ }
- return output_buf;
+ /* We couldn't find that proceesor name, or the processor name we
+ found does not map to an architecture we understand. */
+ if (p_to_a->arch == aarch64_no_arch
+ || a_to_an->arch == aarch64_no_arch)
+ fatal_error (input_location, "unknown value %qs for -mcpu", name);
+
+ std::string outstr = a_to_an->arch_name
+ + aarch64_get_extension_string_for_isa_flags (p_to_a->flags)
+ + extensions;
+
+ /* We are going to memory leak here, nobody elsewhere
+ in the callchain is going to clean up after us. The alternative is
+ to allocate a static buffer, and assert that it is big enough for our
+ modified string, which seems much worse! */
+ return xstrdup (outstr.c_str ());
}
/* Called by the driver to rewrite a name passed to the -mcpu
aarch64_cmodel = opts->x_aarch64_cmodel_var;
}
-/* Print to F the architecture features specified by ISA_FLAGS. */
-
-static void
-aarch64_print_extension (FILE *f, unsigned long isa_flags)
-{
- const struct aarch64_option_extension *opt = NULL;
-
- for (opt = all_extensions; opt->name != NULL; opt++)
- if ((isa_flags & opt->flags_on) == opt->flags_on)
- asm_fprintf (f, "+%s", opt->name);
-
- asm_fprintf (f, "\n");
-}
-
/* Implement TARGET_OPTION_SAVE. */
static void
= aarch64_get_tune_cpu (ptr->x_explicit_tune_core);
unsigned long isa_flags = ptr->x_aarch64_isa_flags;
const struct processor *arch = aarch64_get_arch (ptr->x_explicit_arch);
+ std::string extension
+ = aarch64_get_extension_string_for_isa_flags (isa_flags);
fprintf (file, "%*sselected tune = %s\n", indent, "", cpu->name);
- fprintf (file, "%*sselected arch = %s", indent, "", arch->name);
- aarch64_print_extension (file, isa_flags);
+ fprintf (file, "%*sselected arch = %s%s\n", indent, "",
+ arch->name, extension.c_str ());
}
static GTY(()) tree aarch64_previous_fndecl;
const struct processor *this_arch
= aarch64_get_arch (targ_options->x_explicit_arch);
- asm_fprintf (asm_out_file, "\t.arch %s", this_arch->name);
- aarch64_print_extension (asm_out_file, targ_options->x_aarch64_isa_flags);
+ unsigned long isa_flags = targ_options->x_aarch64_isa_flags;
+ std::string extension
+ = aarch64_get_extension_string_for_isa_flags (isa_flags);
+ asm_fprintf (asm_out_file, "\t.arch %s%s\n",
+ this_arch->name, extension.c_str ());
/* Print the cpu name we're tuning for in the comments, might be
useful to readers of the generated asm. */
{"arch", "%{!march=*:%{!mcpu=*:-march=%(VALUE)}}" }, \
{"cpu", "%{!march=*:%{!mcpu=*:-mcpu=%(VALUE)}}" },
-#define BIG_LITTLE_SPEC \
- " %{mcpu=*:-mcpu=%:rewrite_mcpu(%{mcpu=*:%*})}"
+#define MCPU_TO_MARCH_SPEC \
+ " %{mcpu=*:-march=%:rewrite_mcpu(%{mcpu=*:%*})}"
extern const char *aarch64_rewrite_mcpu (int argc, const char **argv);
-#define BIG_LITTLE_CPU_SPEC_FUNCTIONS \
+#define MCPU_TO_MARCH_SPEC_FUNCTIONS \
{ "rewrite_mcpu", aarch64_rewrite_mcpu },
#if defined(__aarch64__)
extern const char *host_detect_local_cpu (int argc, const char **argv);
# define EXTRA_SPEC_FUNCTIONS \
{ "local_cpu_detect", host_detect_local_cpu }, \
- BIG_LITTLE_CPU_SPEC_FUNCTIONS
+ MCPU_TO_MARCH_SPEC_FUNCTIONS
# define MCPU_MTUNE_NATIVE_SPECS \
" %{march=native:%<march=native %:local_cpu_detect(arch)}" \
" %{mtune=native:%<mtune=native %:local_cpu_detect(tune)}"
#else
# define MCPU_MTUNE_NATIVE_SPECS ""
-# define EXTRA_SPEC_FUNCTIONS BIG_LITTLE_CPU_SPEC_FUNCTIONS
+# define EXTRA_SPEC_FUNCTIONS MCPU_TO_MARCH_SPEC_FUNCTIONS
#endif
#define ASM_CPU_SPEC \
- BIG_LITTLE_SPEC
+ MCPU_TO_MARCH_SPEC
#define EXTRA_SPECS \
{ "asm_cpu_spec", ASM_CPU_SPEC }