summaryrefslogtreecommitdiff
path: root/gcc/config/arm
diff options
context:
space:
mode:
authorams <ams@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-18 14:14:14 +0000
committerams <ams@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-18 14:14:14 +0000
commit2ae1f0cc764e998bfc684d662aba0497e8723e52 (patch)
tree8ecbf80cbd6e807c88fbc66f5ba482431661e5ea /gcc/config/arm
parent24224d3da21a164f17052e355b5810366a442fdb (diff)
downloadgcc-2ae1f0cc764e998bfc684d662aba0497e8723e52.tar.gz
2011-10-18 Andrew Stubbs <ams@codesourcery.com>
gcc/ * config.host (arm*-*-linux*): Add driver-arm.o and x-arm. * config/arm/arm.opt: Add 'native' processor_type and arm_arch enum values. * config/arm/arm.h (host_detect_local_cpu): New prototype. (EXTRA_SPEC_FUNCTIONS): New define. (MCPU_MTUNE_NATIVE_SPECS): New define. (DRIVER_SELF_SPECS): New define. * config/arm/driver-arm.c: New file. * config/arm/x-arm: New file. * doc/invoke.texi (ARM Options): Document -mcpu=native, -mtune=native and -march=native. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180139 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/arm')
-rw-r--r--gcc/config/arm/arm.h17
-rw-r--r--gcc/config/arm/arm.opt10
-rw-r--r--gcc/config/arm/driver-arm.c145
-rw-r--r--gcc/config/arm/x-arm3
4 files changed, 175 insertions, 0 deletions
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 271b44126c3..85e2b9971c4 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -2255,4 +2255,21 @@ extern int making_const_table;
} \
while (0)
+/* -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 },
+
+# 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_SPECS ""
+#endif
+
+#define DRIVER_SELF_SPECS MCPU_MTUNE_NATIVE_SPECS
+
#endif /* ! GCC_ARM_H */
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index e33b460520f..934aa35775e 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -80,6 +80,11 @@ march=
Target RejectNegative Joined Enum(arm_arch) Var(arm_arch_option)
Specify the name of the target architecture
+; Other arm_arch values are loaded from arm-tables.opt
+; but that is a generated file and this is an odd-one-out.
+EnumValue
+Enum(arm_arch) String(native) Value(-1) DriverOnly
+
marm
Target Report RejectNegative InverseMask(THUMB)
Generate code in 32 bit ARM state.
@@ -233,6 +238,11 @@ mtune=
Target RejectNegative Joined Enum(processor_type) Var(arm_tune_option) Init(arm_none)
Tune code for the given processor
+; Other processor_type values are loaded from arm-tables.opt
+; but that is a generated file and this is an odd-one-out.
+EnumValue
+Enum(processor_type) String(native) Value(-1) DriverOnly
+
mwords-little-endian
Target Report RejectNegative Mask(LITTLE_WORDS)
Assume big endian bytes, little endian words. This option is deprecated.
diff --git a/gcc/config/arm/driver-arm.c b/gcc/config/arm/driver-arm.c
new file mode 100644
index 00000000000..43b6e581fbe
--- /dev/null
+++ b/gcc/config/arm/driver-arm.c
@@ -0,0 +1,145 @@
+/* Subroutines for the gcc driver.
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "configargs.h"
+
+struct vendor_cpu {
+ const char *part_no;
+ const char *arch_name;
+ const char *cpu_name;
+};
+
+static struct vendor_cpu arm_cpu_table[] = {
+ {"0x926", "armv5te", "arm926ej-s"},
+ {"0xa26", "armv5te", "arm1026ej-s"},
+ {"0xb02", "armv6k", "mpcore"},
+ {"0xb36", "armv6j", "arm1136j-s"},
+ {"0xb56", "armv6t2", "arm1156t2-s"},
+ {"0xb76", "armv6zk", "arm1176jz-s"},
+ {"0xc05", "armv7-a", "cortex-a5"},
+ {"0xc08", "armv7-a", "cortex-a8"},
+ {"0xc09", "armv7-a", "cortex-a9"},
+ {"0xc0f", "armv7-a", "cortex-a15"},
+ {"0xc14", "armv7-r", "cortex-r4"},
+ {"0xc15", "armv7-r", "cortex-r5"},
+ {"0xc20", "armv6-m", "cortex-m0"},
+ {"0xc21", "armv6-m", "cortex-m1"},
+ {"0xc23", "armv7-m", "cortex-m3"},
+ {"0xc24", "armv7e-m", "cortex-m4"},
+ {NULL, NULL, NULL}
+};
+
+struct {
+ const char *vendor_no;
+ const struct vendor_cpu *vendor_parts;
+} vendors[] = {
+ {"0x41", arm_cpu_table},
+ {NULL, NULL}
+};
+
+/* This will be called by the spec parser in gcc.c when it sees
+ a %:local_cpu_detect(args) construct. Currently it will be called
+ with either "arch", "cpu" or "tune" as argument depending on if
+ -march=native, -mcpu=native or -mtune=native is to be substituted.
+
+ It returns a string containing new command line parameters to be
+ put at the place of the above two options, depending on what CPU
+ this is executed. E.g. "-march=armv7-a" on a Cortex-A8 for
+ -march=native. If the routine can't detect a known processor,
+ the -march or -mtune option is discarded.
+
+ ARGC and ARGV are set depending on the actual arguments given
+ in the spec. */
+const char *
+host_detect_local_cpu (int argc, const char **argv)
+{
+ const char *val = NULL;
+ char buf[128];
+ FILE *f;
+ bool arch;
+ const struct vendor_cpu *cpu_table = NULL;
+
+ if (argc < 1)
+ goto not_found;
+
+ arch = strcmp (argv[0], "arch") == 0;
+ if (!arch && strcmp (argv[0], "cpu") != 0 && strcmp (argv[0], "tune"))
+ goto not_found;
+
+ f = fopen ("/proc/cpuinfo", "r");
+ if (f == NULL)
+ goto not_found;
+
+ while (fgets (buf, sizeof (buf), f) != NULL)
+ {
+ /* Ensure that CPU implementer is ARM (0x41). */
+ if (strncmp (buf, "CPU implementer", sizeof ("CPU implementer") - 1) == 0)
+ {
+ int i;
+ for (i = 0; vendors[i].vendor_no != NULL; i++)
+ if (strstr (buf, vendors[i].vendor_no) != NULL)
+ {
+ cpu_table = vendors[i].vendor_parts;
+ break;
+ }
+ }
+
+ /* Detect arch/cpu. */
+ if (strncmp (buf, "CPU part", sizeof ("CPU part") - 1) == 0)
+ {
+ int i;
+
+ if (cpu_table == NULL)
+ goto not_found;
+
+ for (i = 0; cpu_table[i].part_no != NULL; i++)
+ if (strstr (buf, cpu_table[i].part_no) != NULL)
+ {
+ val = arch ? cpu_table[i].arch_name : cpu_table[i].cpu_name;
+ break;
+ }
+ break;
+ }
+ }
+
+ fclose (f);
+
+ if (val == NULL)
+ goto not_found;
+
+ return concat ("-m", argv[0], "=", val, NULL);
+
+not_found:
+ {
+ unsigned int i;
+ unsigned int opt;
+ const char *search[] = {NULL, "arch"};
+ search[0] = argv[0];
+ for (opt = 0; opt < ARRAY_SIZE (search); opt++)
+ for (i = 0; i < ARRAY_SIZE (configure_default_options); i++)
+ if (strcmp (configure_default_options[i].name, search[opt]) == 0)
+ return concat ("-m", search[opt], "=",
+ configure_default_options[i].value, NULL);
+ return NULL;
+ }
+}
diff --git a/gcc/config/arm/x-arm b/gcc/config/arm/x-arm
new file mode 100644
index 00000000000..51cff1ed48b
--- /dev/null
+++ b/gcc/config/arm/x-arm
@@ -0,0 +1,3 @@
+driver-arm.o: $(srcdir)/config/arm/driver-arm.c \
+ $(CONFIG_H) $(SYSTEM_H)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<