> > Thanks Terry (and everyone else) for explaining why we want to do this in the > driver. The substance of the patch looks good to me, and below are some > comments and nit-picks. (Also, I'm not an ARM maintainer, so this is a > review, not an approval to commit). > > Please make sure to update changelog before committing. >
Thanks Maxim, your comments are great. I accepted all of them and commented two of them that I am not clear. <<snapped>> >> + >> +struct arm_arch_core_flag >> +{ >> + const char *const name; >> + const unsigned long flags; >> +}; >> + >> +static const struct arm_arch_core_flag arm_arch_core_flags[] = >> +{ >> +#undef ARM_CORE >> +#define ARM_CORE(NAME, X, IDENT, ARCH, FLAGS, COSTS) \ >> + {NAME, FLAGS | FL_FOR_ARCH##ARCH}, >> +#include "arm-cores.def" >> +#undef ARM_CORE >> +#undef ARM_ARCH >> +#define ARM_ARCH(NAME, CORE, ARCH, FLAGS) \ >> + {NAME, FLAGS}, >> +#include "arm-arches.def" >> +#undef ARM_ARCH >> + {NULL, 0} >> +}; > > Did you consider implications from mixing ARCHes and CPUs in the same array? > It should not be a problem, but would you please double-check that cases like > "-march=cortex-a15" are properly caught as errors elsewhere in the driver? > Not sure I follow you correctly here. This array is just used for my new arm_target_thumb_only function. It isn't used by any another code in gcc. So I don't think mixing them will break gcc option check mechanism. I tried below command and I can get error message: $ ./install-native/bin/arm-none-eabi-gcc -march=cortex-a15 x.c -S -mthumb arm-none-eabi-gcc: error: unrecognized argument in option '-march=cortex-a15' >> #endif >> diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h >> index 28ffe52..325a81c 100644 >> --- a/gcc/config/arm/arm-protos.h >> +++ b/gcc/config/arm/arm-protos.h >> @@ -325,75 +325,6 @@ extern const char *arm_rewrite_selected_cpu (const char >> *name); >> >> extern bool arm_is_constant_pool_ref (rtx); >> >> -/* Flags used to identify the presence of processor capabilities. */ > > You've lost this comment in the new file. Was it intentional? > The line is used as first line in new file arm-flags.h. BR, Terry Here is updated ChangeLog: gcc/ChangeLog: 2015-03-05 Terry Guo <terry....@arm.com> * common/config/arm/arm-common.c (arm_target_thumb_only): New function. * config/arm/arm-protos.h: Move FL_* stuff into below file and then include it. * config/arm/arm-flags.h: New file for FL_* stuff. * config/arm/arm-opts.h (struct arm_arch_core_flag): New struct. (arm_arch_core_flags): New array for arch/core and flag map. * config/arm/arm.h (TARGET_MODE_SPEC_FUNCTIONS): New SPEC function. (EXTRA_SPEC_FUNCTIONS): Include new SPEC function. (TARGET_MODE_SPECS): New SPEC. (DRIVER_SELF_SPECS): Include new SPEC.
diff --git a/gcc/common/config/arm/arm-common.c b/gcc/common/config/arm/arm-common.c index 86673b7..5efb55e 100644 --- a/gcc/common/config/arm/arm-common.c +++ b/gcc/common/config/arm/arm-common.c @@ -97,6 +97,28 @@ arm_rewrite_mcpu (int argc, const char **argv) return arm_rewrite_selected_cpu (argv[argc - 1]); } +/* Called by driver to check whether the target denoted by current + command line options is thumb-only target. If -march present, + check the last -march option. If no -march, check the last -mcpu + option. */ +const char * +arm_target_thumb_only (int argc, const char **argv) +{ + unsigned int opt; + + if (argc) + { + for (opt = 0; opt < (ARRAY_SIZE (arm_arch_core_flags) - 1); opt++) + if ((strcmp (argv[argc - 1], arm_arch_core_flags[opt].name) == 0) + && ((arm_arch_core_flags[opt].flags & FL_NOTM) == 0)) + return "-mthumb"; + + return NULL; + } + else + return NULL; +} + #undef ARM_CPU_NAME_LENGTH diff --git a/gcc/config/arm/arm-flags.h b/gcc/config/arm/arm-flags.h new file mode 100644 index 0000000..e206ad1 --- /dev/null +++ b/gcc/config/arm/arm-flags.h @@ -0,0 +1,92 @@ +/* Flags used to identify the presence of processor capabilities. + + Copyright (C) 2015 Free Software Foundation, Inc. + Contributed by ARM Ltd. + + 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/>. */ + +#ifndef GCC_ARM_FLAGS_H +#define GCC_ARM_FLAGS_H + +/* Bit values used to identify processor capabilities. */ +#define FL_CO_PROC (1 << 0) /* Has external co-processor bus */ +#define FL_ARCH3M (1 << 1) /* Extended multiply */ +#define FL_MODE26 (1 << 2) /* 26-bit mode support */ +#define FL_MODE32 (1 << 3) /* 32-bit mode support */ +#define FL_ARCH4 (1 << 4) /* Architecture rel 4 */ +#define FL_ARCH5 (1 << 5) /* Architecture rel 5 */ +#define FL_THUMB (1 << 6) /* Thumb aware */ +#define FL_LDSCHED (1 << 7) /* Load scheduling necessary */ +#define FL_STRONG (1 << 8) /* StrongARM */ +#define FL_ARCH5E (1 << 9) /* DSP extensions to v5 */ +#define FL_XSCALE (1 << 10) /* XScale */ +/* spare (1 << 11) */ +#define FL_ARCH6 (1 << 12) /* Architecture rel 6. Adds + media instructions. */ +#define FL_VFPV2 (1 << 13) /* Vector Floating Point V2. */ +#define FL_WBUF (1 << 14) /* Schedule for write buffer ops. + Note: ARM6 & 7 derivatives only. */ +#define FL_ARCH6K (1 << 15) /* Architecture rel 6 K extensions. */ +#define FL_THUMB2 (1 << 16) /* Thumb-2. */ +#define FL_NOTM (1 << 17) /* Instructions not present in the 'M' + profile. */ +#define FL_THUMB_DIV (1 << 18) /* Hardware divide (Thumb mode). */ +#define FL_VFPV3 (1 << 19) /* Vector Floating Point V3. */ +#define FL_NEON (1 << 20) /* Neon instructions. */ +#define FL_ARCH7EM (1 << 21) /* Instructions present in the ARMv7E-M + architecture. */ +#define FL_ARCH7 (1 << 22) /* Architecture 7. */ +#define FL_ARM_DIV (1 << 23) /* Hardware divide (ARM mode). */ +#define FL_ARCH8 (1 << 24) /* Architecture 8. */ +#define FL_CRC32 (1 << 25) /* ARMv8 CRC32 instructions. */ + +#define FL_SMALLMUL (1 << 26) /* Small multiply supported. */ +#define FL_NO_VOLATILE_CE (1 << 27) /* No volatile memory in IT block. */ + +#define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */ +#define FL_IWMMXT2 (1 << 30) /* "Intel Wireless MMX2 technology". */ + +/* Flags that only effect tuning, not available instructions. */ +#define FL_TUNE (FL_WBUF | FL_VFPV2 | FL_STRONG | FL_LDSCHED \ + | FL_CO_PROC) + +#define FL_FOR_ARCH2 FL_NOTM +#define FL_FOR_ARCH3 (FL_FOR_ARCH2 | FL_MODE32) +#define FL_FOR_ARCH3M (FL_FOR_ARCH3 | FL_ARCH3M) +#define FL_FOR_ARCH4 (FL_FOR_ARCH3M | FL_ARCH4) +#define FL_FOR_ARCH4T (FL_FOR_ARCH4 | FL_THUMB) +#define FL_FOR_ARCH5 (FL_FOR_ARCH4 | FL_ARCH5) +#define FL_FOR_ARCH5T (FL_FOR_ARCH5 | FL_THUMB) +#define FL_FOR_ARCH5E (FL_FOR_ARCH5 | FL_ARCH5E) +#define FL_FOR_ARCH5TE (FL_FOR_ARCH5E | FL_THUMB) +#define FL_FOR_ARCH5TEJ FL_FOR_ARCH5TE +#define FL_FOR_ARCH6 (FL_FOR_ARCH5TE | FL_ARCH6) +#define FL_FOR_ARCH6J FL_FOR_ARCH6 +#define FL_FOR_ARCH6K (FL_FOR_ARCH6 | FL_ARCH6K) +#define FL_FOR_ARCH6Z FL_FOR_ARCH6 +#define FL_FOR_ARCH6ZK FL_FOR_ARCH6K +#define FL_FOR_ARCH6T2 (FL_FOR_ARCH6 | FL_THUMB2) +#define FL_FOR_ARCH6M (FL_FOR_ARCH6 & ~FL_NOTM) +#define FL_FOR_ARCH7 ((FL_FOR_ARCH6T2 & ~FL_NOTM) | FL_ARCH7) +#define FL_FOR_ARCH7A (FL_FOR_ARCH7 | FL_NOTM | FL_ARCH6K) +#define FL_FOR_ARCH7VE (FL_FOR_ARCH7A | FL_THUMB_DIV | FL_ARM_DIV) +#define FL_FOR_ARCH7R (FL_FOR_ARCH7A | FL_THUMB_DIV) +#define FL_FOR_ARCH7M (FL_FOR_ARCH7 | FL_THUMB_DIV) +#define FL_FOR_ARCH7EM (FL_FOR_ARCH7M | FL_ARCH7EM) +#define FL_FOR_ARCH8A (FL_FOR_ARCH7VE | FL_ARCH8) + +#endif /* GCC_ARM_FLAGS_H */ diff --git a/gcc/config/arm/arm-opts.h b/gcc/config/arm/arm-opts.h index 039e333..dd727cf 100644 --- a/gcc/config/arm/arm-opts.h +++ b/gcc/config/arm/arm-opts.h @@ -25,6 +25,8 @@ #ifndef ARM_OPTS_H #define ARM_OPTS_H +#include "arm-flags.h" + /* The various ARM cores. */ enum processor_type { @@ -77,4 +79,25 @@ enum arm_tls_type { TLS_GNU, TLS_GNU2 }; + +struct arm_arch_core_flag +{ + const char *const name; + const unsigned long flags; +}; + +static const struct arm_arch_core_flag arm_arch_core_flags[] = +{ +#undef ARM_CORE +#define ARM_CORE(NAME, X, IDENT, ARCH, FLAGS, COSTS) \ + {NAME, FLAGS | FL_FOR_ARCH##ARCH}, +#include "arm-cores.def" +#undef ARM_CORE +#undef ARM_ARCH +#define ARM_ARCH(NAME, CORE, ARCH, FLAGS) \ + {NAME, FLAGS}, +#include "arm-arches.def" +#undef ARM_ARCH + {NULL, 0} +}; #endif diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 28ffe52..0d5f61f 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -22,6 +22,8 @@ #ifndef GCC_ARM_PROTOS_H #define GCC_ARM_PROTOS_H +#include "arm-flags.h" + extern enum unwind_info_type arm_except_unwind_info (struct gcc_options *); extern int use_return_insn (int, rtx); extern bool use_simple_return_p (void); @@ -325,75 +327,6 @@ extern const char *arm_rewrite_selected_cpu (const char *name); extern bool arm_is_constant_pool_ref (rtx); -/* Flags used to identify the presence of processor capabilities. */ - -/* Bit values used to identify processor capabilities. */ -#define FL_CO_PROC (1 << 0) /* Has external co-processor bus */ -#define FL_ARCH3M (1 << 1) /* Extended multiply */ -#define FL_MODE26 (1 << 2) /* 26-bit mode support */ -#define FL_MODE32 (1 << 3) /* 32-bit mode support */ -#define FL_ARCH4 (1 << 4) /* Architecture rel 4 */ -#define FL_ARCH5 (1 << 5) /* Architecture rel 5 */ -#define FL_THUMB (1 << 6) /* Thumb aware */ -#define FL_LDSCHED (1 << 7) /* Load scheduling necessary */ -#define FL_STRONG (1 << 8) /* StrongARM */ -#define FL_ARCH5E (1 << 9) /* DSP extensions to v5 */ -#define FL_XSCALE (1 << 10) /* XScale */ -/* spare (1 << 11) */ -#define FL_ARCH6 (1 << 12) /* Architecture rel 6. Adds - media instructions. */ -#define FL_VFPV2 (1 << 13) /* Vector Floating Point V2. */ -#define FL_WBUF (1 << 14) /* Schedule for write buffer ops. - Note: ARM6 & 7 derivatives only. */ -#define FL_ARCH6K (1 << 15) /* Architecture rel 6 K extensions. */ -#define FL_THUMB2 (1 << 16) /* Thumb-2. */ -#define FL_NOTM (1 << 17) /* Instructions not present in the 'M' - profile. */ -#define FL_THUMB_DIV (1 << 18) /* Hardware divide (Thumb mode). */ -#define FL_VFPV3 (1 << 19) /* Vector Floating Point V3. */ -#define FL_NEON (1 << 20) /* Neon instructions. */ -#define FL_ARCH7EM (1 << 21) /* Instructions present in the ARMv7E-M - architecture. */ -#define FL_ARCH7 (1 << 22) /* Architecture 7. */ -#define FL_ARM_DIV (1 << 23) /* Hardware divide (ARM mode). */ -#define FL_ARCH8 (1 << 24) /* Architecture 8. */ -#define FL_CRC32 (1 << 25) /* ARMv8 CRC32 instructions. */ - -#define FL_SMALLMUL (1 << 26) /* Small multiply supported. */ -#define FL_NO_VOLATILE_CE (1 << 27) /* No volatile memory in IT block. */ - -#define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */ -#define FL_IWMMXT2 (1 << 30) /* "Intel Wireless MMX2 technology". */ - -/* Flags that only effect tuning, not available instructions. */ -#define FL_TUNE (FL_WBUF | FL_VFPV2 | FL_STRONG | FL_LDSCHED \ - | FL_CO_PROC) - -#define FL_FOR_ARCH2 FL_NOTM -#define FL_FOR_ARCH3 (FL_FOR_ARCH2 | FL_MODE32) -#define FL_FOR_ARCH3M (FL_FOR_ARCH3 | FL_ARCH3M) -#define FL_FOR_ARCH4 (FL_FOR_ARCH3M | FL_ARCH4) -#define FL_FOR_ARCH4T (FL_FOR_ARCH4 | FL_THUMB) -#define FL_FOR_ARCH5 (FL_FOR_ARCH4 | FL_ARCH5) -#define FL_FOR_ARCH5T (FL_FOR_ARCH5 | FL_THUMB) -#define FL_FOR_ARCH5E (FL_FOR_ARCH5 | FL_ARCH5E) -#define FL_FOR_ARCH5TE (FL_FOR_ARCH5E | FL_THUMB) -#define FL_FOR_ARCH5TEJ FL_FOR_ARCH5TE -#define FL_FOR_ARCH6 (FL_FOR_ARCH5TE | FL_ARCH6) -#define FL_FOR_ARCH6J FL_FOR_ARCH6 -#define FL_FOR_ARCH6K (FL_FOR_ARCH6 | FL_ARCH6K) -#define FL_FOR_ARCH6Z FL_FOR_ARCH6 -#define FL_FOR_ARCH6ZK FL_FOR_ARCH6K -#define FL_FOR_ARCH6T2 (FL_FOR_ARCH6 | FL_THUMB2) -#define FL_FOR_ARCH6M (FL_FOR_ARCH6 & ~FL_NOTM) -#define FL_FOR_ARCH7 ((FL_FOR_ARCH6T2 & ~FL_NOTM) | FL_ARCH7) -#define FL_FOR_ARCH7A (FL_FOR_ARCH7 | FL_NOTM | FL_ARCH6K) -#define FL_FOR_ARCH7VE (FL_FOR_ARCH7A | FL_THUMB_DIV | FL_ARM_DIV) -#define FL_FOR_ARCH7R (FL_FOR_ARCH7A | FL_THUMB_DIV) -#define FL_FOR_ARCH7M (FL_FOR_ARCH7 | FL_THUMB_DIV) -#define FL_FOR_ARCH7EM (FL_FOR_ARCH7M | FL_ARCH7EM) -#define FL_FOR_ARCH8A (FL_FOR_ARCH7VE | FL_ARCH8) - /* The bits in this mask specify which instructions we are allowed to generate. */ extern unsigned long insn_flags; diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 8c10ea3..6a2dfaf 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -2394,13 +2394,18 @@ extern const char *arm_rewrite_mcpu (int argc, const char **argv); " :%{march=*:-march=%*}}" \ BIG_LITTLE_SPEC +extern const char *arm_target_thumb_only (int argc, const char **argv); +#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 + BIG_LITTLE_CPU_SPEC_FUNCTIONS \ + TARGET_MODE_SPEC_FUNCTIONS # define MCPU_MTUNE_NATIVE_SPECS \ " %{march=native:%<march=native %:local_cpu_detect(arch)}" \ @@ -2408,9 +2413,19 @@ 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 \ + BIG_LITTLE_CPU_SPEC_FUNCTIONS \ + TARGET_MODE_SPEC_FUNCTIONS #endif -#define DRIVER_SELF_SPECS MCPU_MTUNE_NATIVE_SPECS +/* Automatically add -mthumb for thumb-only target if mode isn't specified + via configuration option --with-mode and command line. + If -march present, we collect just -march options. Otherwise we + collect just -mcpu options. The last one of them will be used to + decide target mode. */ +#define TARGET_MODE_SPECS \ + " %{!marm:%{!mthumb:%:target_mode_check(%{march=*:%*;mcpu=*:%*})}}" + +#define DRIVER_SELF_SPECS MCPU_MTUNE_NATIVE_SPECS TARGET_MODE_SPECS #define TARGET_SUPPORTS_WIDE_INT 1 #endif /* ! GCC_ARM_H */