Hi,

As in the ARM backend we would like to use specs to rewrite a
-mcpu=big.LITTLE style name to just -mcpu=big before handing off
to the assembler.

As with the ARM backend, we can do this using ASM_SPEC. We need to
do a little more wiring up here, as the AArch64 backend doesn't
yet use these specs.

Tested on aarch64-none-elf with no regressions, built on
aarch64-none-linux-gnu with no problems.

OK?

Thanks,
James

---
2013-12-18  James Greenhalgh  <james.greenha...@arm.com>

        * common/config/aarch64/aarch64-common.c
        (aarch64_rewrite_selected_cpu): New.
        (aarch64_rewrite_mcpu): New.
        * config/aarch64/aarch64-protos.h
        (aarch64_rewrite_selected_cpu): New.
        * config/aarch64/aarch64.h (BIG_LITTLE_SPEC): New.
        (BIG_LITTLE_SPEC_FUNCTIONS): Likewise.
        (ASM_CPU_SPEC): Likewise.
        (EXTRA_SPEC_FUNCTIONS): Likewise.
        (EXTRA_SPECS): Likewise.
        (ASM_SPEC): Likewise.
        * config/aarch64/aarch64.c (aarch64_start_file): Rewrite target
        CPU name.
diff --git a/gcc/common/config/aarch64/aarch64-common.c b/gcc/common/config/aarch64/aarch64-common.c
index 9c8e770..19acce1 100644
--- a/gcc/common/config/aarch64/aarch64-common.c
+++ b/gcc/common/config/aarch64/aarch64-common.c
@@ -88,3 +88,38 @@ aarch64_handle_option (struct gcc_options *opts,
 }
 
 struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
+
+#define AARCH64_CPU_NAME_LENGTH 20
+
+/* Truncate NAME at the first '.' character seen, or return
+   NAME unmodified.  */
+
+const char *
+aarch64_rewrite_selected_cpu (const char *name)
+{
+  static char output_buf[AARCH64_CPU_NAME_LENGTH + 1] = {0};
+  char *arg_pos;
+
+  strncpy (output_buf, name, AARCH64_CPU_NAME_LENGTH);
+  arg_pos = strchr (output_buf, '.');
+
+  /* If we found a '.' truncate the entry at that point.  */
+  if (arg_pos)
+    *arg_pos = '\0';
+
+  return output_buf;
+}
+
+/* Called by the driver to rewrite a name passed to the -mcpu
+   argument in preparation to be passed to the assembler.  The
+   name will be in ARGV[0], ARGC should always be 1.  */
+
+const char *
+aarch64_rewrite_mcpu (int argc, const char **argv)
+{
+  gcc_assert (argc == 1);
+  return aarch64_rewrite_selected_cpu (argv[0]);
+}
+
+#undef AARCH64_CPU_NAME_LENGTH
+
diff --git a/gcc/config/aarch64/aarch64-elf.h b/gcc/config/aarch64/aarch64-elf.h
index a66c3db..97e1fb5 100644
--- a/gcc/config/aarch64/aarch64-elf.h
+++ b/gcc/config/aarch64/aarch64-elf.h
@@ -145,7 +145,8 @@
 %{mbig-endian:-EB} \
 %{mlittle-endian:-EL} \
 %{mcpu=*:-mcpu=%*} \
-%{march=*:-march=%*}" \
+%{march=*:-march=%*} \
+%(asm_cpu_spec)" \
 ASM_MABI_SPEC
 #endif
 
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 489fd1c..6ac059b 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -189,6 +189,8 @@ bool aarch64_simd_valid_immediate (rtx, enum machine_mode, bool,
 bool aarch64_symbolic_address_p (rtx);
 bool aarch64_uimm12_shift (HOST_WIDE_INT);
 const char *aarch64_output_casesi (rtx *);
+const char *aarch64_rewrite_selected_cpu (const char *name);
+
 enum aarch64_symbol_type aarch64_classify_symbol (rtx,
 						  enum aarch64_symbol_context);
 enum aarch64_symbol_type aarch64_classify_tls_symbol (rtx);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index afcf43f..0c53e64 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -7437,7 +7437,9 @@ aarch64_start_file (void)
     }
   else if (selected_cpu)
     {
-      asm_fprintf (asm_out_file, "\t.cpu %s", selected_cpu->name);
+      const char *truncated_name
+	    = aarch64_rewrite_selected_cpu (selected_cpu->name);
+      asm_fprintf (asm_out_file, "\t.cpu %s", truncated_name);
       aarch64_print_extension ();
     }
   default_file_start();
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index cead022..d89c09b 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -857,4 +857,19 @@ extern enum aarch64_code_model aarch64_cmodel;
 #define ENDIAN_LANE_N(mode, n)  \
   (BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 - n : n)
 
+#define BIG_LITTLE_SPEC \
+   " %{mcpu=*:%<mcpu=* -mcpu=%:rewrite_mcpu(%{mcpu=*:%*})}"
+
+extern const char *aarch64_rewrite_mcpu (int argc, const char **argv);
+#define BIG_LITTLE_CPU_SPEC_FUNCTIONS \
+  { "rewrite_mcpu", aarch64_rewrite_mcpu },
+
+#define ASM_CPU_SPEC \
+   BIG_LITTLE_SPEC
+
+#define EXTRA_SPEC_FUNCTIONS BIG_LITTLE_CPU_SPEC_FUNCTIONS
+
+#define EXTRA_SPECS						\
+  { "asm_cpu_spec",		ASM_CPU_SPEC }
+
 #endif /* GCC_AARCH64_H */

Reply via email to