summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>2017-06-16 21:01:29 +0000
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>2017-06-16 21:01:29 +0000
commitceb0f143c2bd2dc4a2a68082ff3fe456cefcecc0 (patch)
treebcdd048963fde9c7926aee8fd673d28fe990ba93
parenta99ae290af49793cd3db7a74f3dbc59e64d356a1 (diff)
downloadgcc-ceb0f143c2bd2dc4a2a68082ff3fe456cefcecc0.tar.gz
[arm] Rewrite -march and -mcpu options for passing to
The assembler does not understand all the '+' options accepted by the compiler. The best solution to this is to simply strip the extensions and just pass the raw architecture or cpu name through to the assembler. We will use .arch and .arch_extension directives anyway to turn on or off individual features. We already do something similar for big.little combinations and this just extends this principle a bit further. This patch also fixes a possible bug by ensuring that the limited string copy is correctly NUL-terminated. While messing with this code I've also taken the opportunity to clean up the duplicate definitions of EXTRA_SPEC_FUNCTIONS by moving it outside of the ifdef wrapper. * config/arm/arm.h (BIG_LITTLE_SPEC): Delete macro. (ASM_REWRITE_SPEC_FUNCTIONS): New macro. (BIG_LITTLE_CPU_SPEC_FUNCTIONS): Delete macro. (ASM_CPU_SPEC): Rewrite. (MCPU_MTUNE_NATIVE_FUNCTIONS): New macro. (EXTRA_SPEC_FUNCTIONS): Move outside of ifdef. Use MCPU_MTUNE_NATIVE_FUNCTIONS and ASM_REWRITE_SPEC_FUNCTIONS. Remove reference to BIG_LITTLE_CPU_SPEC_FUNCTIONS. * common/config/arm/arm-common.c (arm_rewrite_selected_cpu): Ensure copied string is NUL-terminated. Also strip any characters prefixed by '+'. (arm_rewrite_selected_arch): New function. (arm_rewrite_march): New function. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@249280 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/common/config/arm/arm-common.c45
-rw-r--r--gcc/config/arm/arm.h42
3 files changed, 81 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 61236929a59..1542ae3467d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,21 @@
2017-06-16 Richard Earnshaw <rearnsha@arm.com>
+ * config/arm/arm.h (BIG_LITTLE_SPEC): Delete macro.
+ (ASM_REWRITE_SPEC_FUNCTIONS): New macro.
+ (BIG_LITTLE_CPU_SPEC_FUNCTIONS): Delete macro.
+ (ASM_CPU_SPEC): Rewrite.
+ (MCPU_MTUNE_NATIVE_FUNCTIONS): New macro.
+ (EXTRA_SPEC_FUNCTIONS): Move outside of ifdef. Use
+ MCPU_MTUNE_NATIVE_FUNCTIONS and ASM_REWRITE_SPEC_FUNCTIONS. Remove
+ reference to BIG_LITTLE_CPU_SPEC_FUNCTIONS.
+ * common/config/arm/arm-common.c (arm_rewrite_selected_cpu): Ensure
+ copied string is NUL-terminated. Also strip any characters prefixed
+ by '+'.
+ (arm_rewrite_selected_arch): New function.
+ (arm_rewrite_march): New function.
+
+2017-06-16 Richard Earnshaw <rearnsha@arm.com>
+
* config/arm/arm.opt (x_arm_arch_string): New TargetSave option.
(x_arm_cpu_string, x_arm_tune_string): Likewise.
(march, mcpu, mtune): Convert to string-based options.
diff --git a/gcc/common/config/arm/arm-common.c b/gcc/common/config/arm/arm-common.c
index 7ecc68d6757..fd0c6165541 100644
--- a/gcc/common/config/arm/arm-common.c
+++ b/gcc/common/config/arm/arm-common.c
@@ -66,7 +66,7 @@ arm_except_unwind_info (struct gcc_options *opts)
#define ARM_CPU_NAME_LENGTH 20
-/* Truncate NAME at the first '.' character seen, or return
+/* Truncate NAME at the first '.' or '+' character seen, or return
NAME unmodified. */
const char *
@@ -76,12 +76,20 @@ arm_rewrite_selected_cpu (const char *name)
char *arg_pos;
strncpy (output_buf, name, ARM_CPU_NAME_LENGTH);
+ output_buf[ARM_CPU_NAME_LENGTH] = 0;
+
arg_pos = strchr (output_buf, '.');
/* If we found a '.' truncate the entry at that point. */
if (arg_pos)
*arg_pos = '\0';
+ arg_pos = strchr (output_buf, '+');
+
+ /* If we found a '+' truncate the entry at that point. */
+ if (arg_pos)
+ *arg_pos = '\0';
+
return output_buf;
}
@@ -98,6 +106,41 @@ arm_rewrite_mcpu (int argc, const char **argv)
return arm_rewrite_selected_cpu (argv[argc - 1]);
}
+/* Truncate NAME at the first '+' character seen, or return
+ NAME unmodified. Similar to arm_rewrite_selected_cpu, but we must
+ preserve '.' as that is part of some architecture names. */
+
+const char *
+arm_rewrite_selected_arch (const char *name)
+{
+ static char output_buf[ARM_CPU_NAME_LENGTH + 1] = {0};
+ char *arg_pos;
+
+ strncpy (output_buf, name, ARM_CPU_NAME_LENGTH);
+ output_buf[ARM_CPU_NAME_LENGTH] = 0;
+
+ 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 -march
+ argument in preparation to be passed to the assembler. The
+ names passed from the command line will be in ARGV, we want
+ to use the right-most argument, which should be in
+ ARGV[ARGC - 1]. ARGC should always be greater than 0. */
+
+const char *
+arm_rewrite_march (int argc, const char **argv)
+{
+ gcc_assert (argc);
+ return arm_rewrite_selected_arch (argv[argc - 1]);
+}
+
struct arm_arch_core_flag
{
const char *const name;
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index f9e4356756a..d398b99fbb2 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -2219,42 +2219,42 @@ extern int making_const_table;
instruction. */
#define MAX_LDM_STM_OPS 4
-#define BIG_LITTLE_SPEC \
- " %{mcpu=*:-mcpu=%:rewrite_mcpu(%{mcpu=*:%*})}"
-
extern const char *arm_rewrite_mcpu (int argc, const char **argv);
-#define BIG_LITTLE_CPU_SPEC_FUNCTIONS \
- { "rewrite_mcpu", arm_rewrite_mcpu },
+extern const char *arm_rewrite_march (int argc, const char **argv);
+#define ASM_CPU_SPEC_FUNCTIONS \
+ { "rewrite_mcpu", arm_rewrite_mcpu }, \
+ { "rewrite_march", arm_rewrite_march },
-#define ASM_CPU_SPEC \
- " %{mcpu=generic-*:-march=%*;" \
- " :%{march=*:-march=%*}}" \
- BIG_LITTLE_SPEC
+#define ASM_CPU_SPEC \
+ " %{mcpu=generic-*:-march=%:rewrite_march(%{mcpu=generic-*:%*});" \
+ " march=*:-march=%:rewrite_march(%{march=*:%*});" \
+ " mcpu=*:-mcpu=%:rewrite_mcpu(%{mcpu=*:%*})" \
+ " }"
extern const char *arm_target_thumb_only (int argc, const char **argv);
-#define TARGET_MODE_SPEC_FUNCTIONS \
+#define TARGET_MODE_SPEC_FUNCTIONS \
{ "target_mode_check", arm_target_thumb_only },
/* -mcpu=native handling only makes sense with compiler running on
an ARM chip. */
#if defined(__arm__)
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 \
- TARGET_MODE_SPEC_FUNCTIONS
-
-# define MCPU_MTUNE_NATIVE_SPECS \
- " %{march=native:%<march=native %:local_cpu_detect(arch)}" \
- " %{mcpu=native:%<mcpu=native %:local_cpu_detect(cpu)}" \
+# define MCPU_MTUNE_NATIVE_FUNCTIONS \
+ { "local_cpu_detect", host_detect_local_cpu },
+# define MCPU_MTUNE_NATIVE_SPECS \
+ " %{march=native:%<march=native %:local_cpu_detect(arch)}" \
+ " %{mcpu=native:%<mcpu=native %:local_cpu_detect(cpu)}" \
" %{mtune=native:%<mtune=native %:local_cpu_detect(tune)}"
#else
+# define MCPU_MTUNE_NATIVE_FUNCTIONS
# define MCPU_MTUNE_NATIVE_SPECS ""
-# define EXTRA_SPEC_FUNCTIONS \
- BIG_LITTLE_CPU_SPEC_FUNCTIONS \
- TARGET_MODE_SPEC_FUNCTIONS
#endif
+# define EXTRA_SPEC_FUNCTIONS \
+ MCPU_MTUNE_NATIVE_FUNCTIONS \
+ ASM_CPU_SPEC_FUNCTIONS \
+ TARGET_MODE_SPEC_FUNCTIONS
+
/* Automatically add -mthumb for Thumb-only targets if mode isn't specified
via the configuration option --with-mode or via the command line. The
function target_mode_check is called to do the check with either: