[AArch64] Break -mcpu tie between the compiler and assembler
authorJames Greenhalgh <james.greenhalgh@arm.com>
Thu, 20 Aug 2015 10:18:54 +0000 (10:18 +0000)
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>
Thu, 20 Aug 2015 10:18:54 +0000 (10:18 +0000)
gcc/

* 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.

From-SVN: r227028

gcc/ChangeLog
gcc/common/config/aarch64/aarch64-common.c
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.h

index 62459e78af6fca4a5e910d3aa192817787f58bdc..a42d61e484aff24749343bbb5c4bc337208ea7b9 100644 (file)
@@ -1,3 +1,29 @@
+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
index 726c62531d9b809cc8b0b2aafcb6380627126158..07c6bba45198867abce6857d7f147d193269aca9 100644 (file)
@@ -27,7 +27,7 @@
 #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
@@ -107,36 +107,134 @@ aarch64_handle_option (struct gcc_options *opts,
 
 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
index 0b09d49f6702c7734c05c907788d4e2231701355..06002d8c04b41cbe94976060ebb3f7c9c6fc0486 100644 (file)
@@ -310,6 +310,7 @@ rtx aarch64_simd_gen_const_vector_dup (machine_mode, int);
 bool aarch64_simd_mem_operand_p (rtx);
 rtx aarch64_simd_vect_par_cnst_half (machine_mode, bool);
 rtx aarch64_tls_get_addr (void);
+std::string aarch64_get_extension_string_for_isa_flags (unsigned long);
 tree aarch64_fold_builtin (tree, int, tree *, bool);
 unsigned aarch64_dbx_register_number (unsigned);
 unsigned aarch64_trampoline_size (void);
index 382be2c059f65d08c7afca09e4ab2f9b9bd8e741..8e28ababef71c79a2f3655baf1fd267865560b56 100644 (file)
@@ -7890,20 +7890,6 @@ initialize_aarch64_code_model (struct gcc_options *opts)
      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
@@ -7936,10 +7922,12 @@ aarch64_option_print (FILE *file, int indent, struct cl_target_option *ptr)
     = 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;
@@ -10663,8 +10651,11 @@ aarch64_declare_function_name (FILE *stream, const char* name,
   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.  */
index 1be78fc16dd5d739dcab29fc01c0a29d526f886b..1e5f5dbd4fa3b11c167df8cb5965c41c9362a5ee 100644 (file)
@@ -887,18 +887,18 @@ extern enum aarch64_code_model aarch64_cmodel;
   {"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)}"          \
@@ -906,11 +906,11 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
    " %{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 }