[arm] Allow +opt on arbitrary cpu and architecture
authorRichard Earnshaw <rearnsha@arm.com>
Fri, 16 Jun 2017 21:02:10 +0000 (21:02 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Fri, 16 Jun 2017 21:02:10 +0000 (21:02 +0000)
This is the main patch to provide the infrastructure for adding
feature extensions to CPU and architecture specifications.  It does not,
however, add all the extensions that we intend to support (just a small
number to permit some basic testing).  Now, instead of having specific
entries in the architecture table for variants such as armv8-a+crc, the
crc extension is specified as an optional component of the armv8-a
architecture entry.  Similar control can be added to CPU option names.
In both cases the list of permitted options is controlled by the main
architecture or CPU name to prevent arbitrary cross-products of options.

* config/arm/arm-cpus.in (armv8-a): Add options crc, simd crypto and
nofp.
(armv8-a+crc): Delete.
(armv8.1-a): Add options simd, crypto and nofp.
(armv8.2-a): Add options fp16, simd, crypto and nofp.
(armv8.2-a+fp16): Delete.
(armv8-m.main): Add option dsp.
(armv8-m.main+dsp): Delete.
(cortex-a8): Add fpu.  Add nofp option.
(cortex-a9): Add fpu.  Add nofp and nosimd options.
* config/arm/parsecpu.awk (gen_data): Generate option tables and
link to main cpu and architecture data structures.
(gen_comm_data): Only put isa attributes from the main architecture
in common tables.
(option): New statement for architecture and CPU entries.
* arm.c (struct cpu_option): New structure.
(struct processors): Add entry for options.
(arm_unrecognized_feature): New function.
(arm_parse_arch_cpu_name): Ignore any characters after the first
'+' character.
(arm_parse_arch_cpu_feature): New function.
(arm_configure_build_target): Separate out any CPU and architecture
features and parse separately.  Don't error out if -mfpu=auto is
used with only an architecture string.
(arm_print_asm_arch_directives): New function.
(arm_file_start): Call it.
* config/arm/arm-cpu-cdata.h: Regenerated.
* config/arm/arm-cpu-data.h: Likewise.
* config/arm/arm-tables.opt: Likewise.

From-SVN: r249282

gcc/ChangeLog
gcc/config/arm/arm-cpu-cdata.h
gcc/config/arm/arm-cpu-data.h
gcc/config/arm/arm-cpus.in
gcc/config/arm/arm-tables.opt
gcc/config/arm/arm.c
gcc/config/arm/parsecpu.awk

index 5ea21b74716f02164263d31accab8927128588a9..67ebd1cc49f0d4ee425946dcdeaceb5621ab31a3 100644 (file)
@@ -1,3 +1,35 @@
+2017-06-16  Richard Earnshaw  <rearnsha@arm.com>
+
+       * config/arm/arm-cpus.in (armv8-a): Add options crc, simd crypto and
+       nofp.
+       (armv8-a+crc): Delete.
+       (armv8.1-a): Add options simd, crypto and nofp.
+       (armv8.2-a): Add options fp16, simd, crypto and nofp.
+       (armv8.2-a+fp16): Delete.
+       (armv8-m.main): Add option dsp.
+       (armv8-m.main+dsp): Delete.
+       (cortex-a8): Add fpu.  Add nofp option.
+       (cortex-a9): Add fpu.  Add nofp and nosimd options.
+       * config/arm/parsecpu.awk (gen_data): Generate option tables and
+       link to main cpu and architecture data structures.
+       (gen_comm_data): Only put isa attributes from the main architecture
+       in common tables.
+       (option): New statement for architecture and CPU entries.
+       * arm.c (struct cpu_option): New structure.
+       (struct processors): Add entry for options.
+       (arm_unrecognized_feature): New function.
+       (arm_parse_arch_cpu_name): Ignore any characters after the first
+       '+' character.
+       (arm_parse_arch_cpu_feature): New function.
+       (arm_configure_build_target): Separate out any CPU and architecture
+       features and parse separately.  Don't error out if -mfpu=auto is
+       used with only an architecture string.
+       (arm_print_asm_arch_directives): New function.
+       (arm_file_start): Call it.
+       * config/arm/arm-cpu-cdata.h: Regenerated.
+       * config/arm/arm-cpu-data.h: Likewise.
+       * config/arm/arm-tables.opt: Likewise.
+
 2017-06-16  Richard Earnshaw  <rearnsha@arm.com>
 
        * config/arm/elf.h (ASM_SPEC): Only pass -mfpu through to the
index b00d83302f6473583e291b16ddb05e3d9ed8f1b6..a64413dc45fddb3dbd5bd62f1cea1f92bbff5615 100644 (file)
@@ -577,6 +577,7 @@ static const struct arm_arch_core_flag arm_arch_core_flags[] =
     "cortex-a8",
     {
       ISA_ARMv7a,
+      ISA_VFPv3,ISA_NEON,
       isa_nobit
     },
   },
@@ -584,6 +585,7 @@ static const struct arm_arch_core_flag arm_arch_core_flags[] =
     "cortex-a9",
     {
       ISA_ARMv7a,
+      ISA_VFPv3,ISA_NEON,
       isa_nobit
     },
   },
@@ -693,49 +695,49 @@ static const struct arm_arch_core_flag arm_arch_core_flags[] =
   {
     "cortex-a32",
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
       isa_nobit
     },
   },
   {
     "cortex-a35",
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
       isa_nobit
     },
   },
   {
     "cortex-a53",
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
       isa_nobit
     },
   },
   {
     "cortex-a57",
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
       isa_nobit
     },
   },
   {
     "cortex-a72",
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
       isa_nobit
     },
   },
   {
     "cortex-a73",
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
       isa_nobit
     },
   },
   {
     "exynos-m1",
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
       isa_nobit
     },
   },
@@ -749,28 +751,28 @@ static const struct arm_arch_core_flag arm_arch_core_flags[] =
   {
     "cortex-a57.cortex-a53",
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
       isa_nobit
     },
   },
   {
     "cortex-a72.cortex-a53",
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
       isa_nobit
     },
   },
   {
     "cortex-a73.cortex-a35",
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
       isa_nobit
     },
   },
   {
     "cortex-a73.cortex-a53",
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
       isa_nobit
     },
   },
@@ -784,7 +786,7 @@ static const struct arm_arch_core_flag arm_arch_core_flags[] =
   {
     "cortex-m33",
     {
-      ISA_ARMv8m_main,isa_bit_ARMv7em,
+      ISA_ARMv8m_main,
       isa_nobit
     },
   },
@@ -977,13 +979,6 @@ static const struct arm_arch_core_flag arm_arch_core_flags[] =
       isa_nobit
     },
   },
-  {
-    "armv8-a+crc",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
-  },
   {
     "armv8.1-a",
     {
@@ -998,13 +993,6 @@ static const struct arm_arch_core_flag arm_arch_core_flags[] =
       isa_nobit
     },
   },
-  {
-    "armv8.2-a+fp16",
-    {
-      ISA_ARMv8_2a,isa_bit_fp16,
-      isa_nobit
-    },
-  },
   {
     "armv8-m.base",
     {
@@ -1019,13 +1007,6 @@ static const struct arm_arch_core_flag arm_arch_core_flags[] =
       isa_nobit
     },
   },
-  {
-    "armv8-m.main+dsp",
-    {
-      ISA_ARMv8m_main,isa_bit_ARMv7em,
-      isa_nobit
-    },
-  },
   {
     "iwmmxt",
     {
index 78421adb9e5cafad1d7a5384c114daca2e2b3a8a..6ec0d3bc7d3290b66cef02a3534914fe744e5f29 100644 (file)
    License along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
+static const struct cpu_option cpu_opttab_cortexa8[] = {
+  {
+    "nofp", true,
+    { ISA_NEON,ISA_VFPv3, isa_nobit }
+  },
+  { NULL, false, {isa_nobit}}
+};
+
+static const struct cpu_option cpu_opttab_cortexa9[] = {
+  {
+    "nofp", true,
+    { ISA_NEON,ISA_VFPv3, isa_nobit }
+  },
+  {
+    "nosimd", true,
+    { ISA_NEON, isa_nobit }
+  },
+  { NULL, false, {isa_nobit}}
+};
+
 static const struct processors all_cores[] =
 {
   {
@@ -31,6 +51,7 @@ static const struct processors all_cores[] =
       ISA_ARMv2,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -42,6 +63,7 @@ static const struct processors all_cores[] =
       ISA_ARMv2,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -53,6 +75,7 @@ static const struct processors all_cores[] =
       ISA_ARMv2,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -64,6 +87,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -75,6 +99,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -86,6 +111,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -97,6 +123,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -108,6 +135,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -119,6 +147,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -130,6 +159,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -141,6 +171,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -152,6 +183,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -163,6 +195,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -174,6 +207,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -185,6 +219,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -196,6 +231,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -207,6 +243,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -218,6 +255,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -229,6 +267,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -240,6 +279,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_slowmul_tune
   },
   {
@@ -251,6 +291,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3m,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -262,6 +303,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3m,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -273,6 +315,7 @@ static const struct processors all_cores[] =
       ISA_ARMv3m,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -284,6 +327,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -295,6 +339,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -306,6 +351,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_strongarm_tune
   },
   {
@@ -317,6 +363,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_strongarm_tune
   },
   {
@@ -328,6 +375,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_strongarm_tune
   },
   {
@@ -339,6 +387,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_strongarm_tune
   },
   {
@@ -350,6 +399,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -361,6 +411,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -372,6 +423,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -383,6 +435,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -394,6 +447,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -405,6 +459,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -416,6 +471,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -427,6 +483,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -438,6 +495,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -449,6 +507,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -460,6 +519,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -471,6 +531,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -482,6 +543,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -493,6 +555,7 @@ static const struct processors all_cores[] =
       ISA_ARMv4t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -504,6 +567,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -515,6 +579,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5t,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -526,6 +591,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5te,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -537,6 +603,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5te,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -548,6 +615,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5te,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -559,6 +627,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5te,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -570,6 +639,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5te,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -581,6 +651,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5te,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -592,6 +663,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5te,
       isa_nobit
     },
+    NULL,
     &arm_fastmul_tune
   },
   {
@@ -604,6 +676,7 @@ static const struct processors all_cores[] =
       isa_bit_xscale,
       isa_nobit
     },
+    NULL,
     &arm_xscale_tune
   },
   {
@@ -615,6 +688,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,
       isa_nobit
     },
+    NULL,
     &arm_xscale_tune
   },
   {
@@ -626,6 +700,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,isa_bit_iwmmxt2,
       isa_nobit
     },
+    NULL,
     &arm_xscale_tune
   },
   {
@@ -637,6 +712,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5te,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -648,6 +724,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5te,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -659,6 +736,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5te,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -670,6 +748,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5te,
       isa_nobit
     },
+    NULL,
     &arm_fa726te_tune
   },
   {
@@ -681,6 +760,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5tej,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -692,6 +772,7 @@ static const struct processors all_cores[] =
       ISA_ARMv5tej,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -703,6 +784,7 @@ static const struct processors all_cores[] =
       ISA_ARMv6j,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -715,6 +797,7 @@ static const struct processors all_cores[] =
       ISA_VFPv2,ISA_FP_DBL,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -726,6 +809,7 @@ static const struct processors all_cores[] =
       ISA_ARMv6kz,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -738,6 +822,7 @@ static const struct processors all_cores[] =
       ISA_VFPv2,ISA_FP_DBL,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -749,6 +834,7 @@ static const struct processors all_cores[] =
       ISA_ARMv6k,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -761,6 +847,7 @@ static const struct processors all_cores[] =
       ISA_VFPv2,ISA_FP_DBL,
       isa_nobit
     },
+    NULL,
     &arm_9e_tune
   },
   {
@@ -772,6 +859,7 @@ static const struct processors all_cores[] =
       ISA_ARMv6t2,
       isa_nobit
     },
+    NULL,
     &arm_v6t2_tune
   },
   {
@@ -784,6 +872,7 @@ static const struct processors all_cores[] =
       ISA_VFPv2,ISA_FP_DBL,
       isa_nobit
     },
+    NULL,
     &arm_v6t2_tune
   },
   {
@@ -795,6 +884,7 @@ static const struct processors all_cores[] =
       ISA_ARMv6m,
       isa_nobit
     },
+    NULL,
     &arm_v6m_tune
   },
   {
@@ -806,6 +896,7 @@ static const struct processors all_cores[] =
       ISA_ARMv6m,
       isa_nobit
     },
+    NULL,
     &arm_v6m_tune
   },
   {
@@ -817,6 +908,7 @@ static const struct processors all_cores[] =
       ISA_ARMv6m,
       isa_nobit
     },
+    NULL,
     &arm_v6m_tune
   },
   {
@@ -828,6 +920,7 @@ static const struct processors all_cores[] =
       ISA_ARMv6m,
       isa_nobit
     },
+    NULL,
     &arm_v6m_tune
   },
   {
@@ -839,6 +932,7 @@ static const struct processors all_cores[] =
       ISA_ARMv6m,
       isa_nobit
     },
+    NULL,
     &arm_v6m_tune
   },
   {
@@ -850,6 +944,7 @@ static const struct processors all_cores[] =
       ISA_ARMv6m,
       isa_nobit
     },
+    NULL,
     &arm_v6m_tune
   },
   {
@@ -861,6 +956,7 @@ static const struct processors all_cores[] =
       ISA_ARMv7a,
       isa_nobit
     },
+    NULL,
     &arm_cortex_tune
   },
   {
@@ -872,6 +968,7 @@ static const struct processors all_cores[] =
       ISA_ARMv7a,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a5_tune
   },
   {
@@ -883,6 +980,7 @@ static const struct processors all_cores[] =
       ISA_ARMv7ve,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a7_tune
   },
   {
@@ -892,8 +990,10 @@ static const struct processors all_cores[] =
     "7A", BASE_ARCH_7A,
     {
       ISA_ARMv7a,
+      ISA_VFPv3,ISA_NEON,
       isa_nobit
     },
+    cpu_opttab_cortexa8,
     &arm_cortex_a8_tune
   },
   {
@@ -903,8 +1003,10 @@ static const struct processors all_cores[] =
     "7A", BASE_ARCH_7A,
     {
       ISA_ARMv7a,
+      ISA_VFPv3,ISA_NEON,
       isa_nobit
     },
+    cpu_opttab_cortexa9,
     &arm_cortex_a9_tune
   },
   {
@@ -916,6 +1018,7 @@ static const struct processors all_cores[] =
       ISA_ARMv7ve,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a12_tune
   },
   {
@@ -927,6 +1030,7 @@ static const struct processors all_cores[] =
       ISA_ARMv7ve,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a15_tune
   },
   {
@@ -938,6 +1042,7 @@ static const struct processors all_cores[] =
       ISA_ARMv7ve,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a12_tune
   },
   {
@@ -949,6 +1054,7 @@ static const struct processors all_cores[] =
       ISA_ARMv7r,
       isa_nobit
     },
+    NULL,
     &arm_cortex_tune
   },
   {
@@ -960,6 +1066,7 @@ static const struct processors all_cores[] =
       ISA_ARMv7r,
       isa_nobit
     },
+    NULL,
     &arm_cortex_tune
   },
   {
@@ -972,6 +1079,7 @@ static const struct processors all_cores[] =
       isa_bit_adiv,
       isa_nobit
     },
+    NULL,
     &arm_cortex_tune
   },
   {
@@ -984,6 +1092,7 @@ static const struct processors all_cores[] =
       isa_bit_adiv,
       isa_nobit
     },
+    NULL,
     &arm_cortex_tune
   },
   {
@@ -996,6 +1105,7 @@ static const struct processors all_cores[] =
       isa_bit_adiv,
       isa_nobit
     },
+    NULL,
     &arm_cortex_tune
   },
   {
@@ -1008,6 +1118,7 @@ static const struct processors all_cores[] =
       isa_quirk_no_volatile_ce,
       isa_nobit
     },
+    NULL,
     &arm_cortex_m7_tune
   },
   {
@@ -1019,6 +1130,7 @@ static const struct processors all_cores[] =
       ISA_ARMv7em,
       isa_nobit
     },
+    NULL,
     &arm_v7m_tune
   },
   {
@@ -1031,6 +1143,7 @@ static const struct processors all_cores[] =
       isa_quirk_cm3_ldrd,
       isa_nobit
     },
+    NULL,
     &arm_v7m_tune
   },
   {
@@ -1042,6 +1155,7 @@ static const struct processors all_cores[] =
       ISA_ARMv7a,
       isa_nobit
     },
+    NULL,
     &arm_marvell_pj4_tune
   },
   {
@@ -1053,6 +1167,7 @@ static const struct processors all_cores[] =
       ISA_ARMv7ve,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a15_tune
   },
   {
@@ -1064,6 +1179,7 @@ static const struct processors all_cores[] =
       ISA_ARMv7ve,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a12_tune
   },
   {
@@ -1072,9 +1188,11 @@ static const struct processors all_cores[] =
     (TF_LDSCHED),
     "8A", BASE_ARCH_8A,
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
+      isa_bit_crc32,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a35_tune
   },
   {
@@ -1083,9 +1201,11 @@ static const struct processors all_cores[] =
     (TF_LDSCHED),
     "8A", BASE_ARCH_8A,
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
+      isa_bit_crc32,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a35_tune
   },
   {
@@ -1094,9 +1214,11 @@ static const struct processors all_cores[] =
     (TF_LDSCHED),
     "8A", BASE_ARCH_8A,
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
+      isa_bit_crc32,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a53_tune
   },
   {
@@ -1105,9 +1227,11 @@ static const struct processors all_cores[] =
     (TF_LDSCHED),
     "8A", BASE_ARCH_8A,
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
+      isa_bit_crc32,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a57_tune
   },
   {
@@ -1116,9 +1240,11 @@ static const struct processors all_cores[] =
     (TF_LDSCHED),
     "8A", BASE_ARCH_8A,
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
+      isa_bit_crc32,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a57_tune
   },
   {
@@ -1127,9 +1253,11 @@ static const struct processors all_cores[] =
     (TF_LDSCHED),
     "8A", BASE_ARCH_8A,
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
+      isa_bit_crc32,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a73_tune
   },
   {
@@ -1138,9 +1266,11 @@ static const struct processors all_cores[] =
     (TF_LDSCHED),
     "8A", BASE_ARCH_8A,
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
+      isa_bit_crc32,
       isa_nobit
     },
+    NULL,
     &arm_exynosm1_tune
   },
   {
@@ -1152,6 +1282,7 @@ static const struct processors all_cores[] =
       ISA_ARMv8a,
       isa_nobit
     },
+    NULL,
     &arm_xgene1_tune
   },
   {
@@ -1160,9 +1291,11 @@ static const struct processors all_cores[] =
     (TF_LDSCHED),
     "8A", BASE_ARCH_8A,
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
+      isa_bit_crc32,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a57_tune
   },
   {
@@ -1171,9 +1304,11 @@ static const struct processors all_cores[] =
     (TF_LDSCHED),
     "8A", BASE_ARCH_8A,
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
+      isa_bit_crc32,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a57_tune
   },
   {
@@ -1182,9 +1317,11 @@ static const struct processors all_cores[] =
     (TF_LDSCHED),
     "8A", BASE_ARCH_8A,
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
+      isa_bit_crc32,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a73_tune
   },
   {
@@ -1193,9 +1330,11 @@ static const struct processors all_cores[] =
     (TF_LDSCHED),
     "8A", BASE_ARCH_8A,
     {
-      ISA_ARMv8a,isa_bit_crc32,
+      ISA_ARMv8a,
+      isa_bit_crc32,
       isa_nobit
     },
+    NULL,
     &arm_cortex_a73_tune
   },
   {
@@ -1207,6 +1346,7 @@ static const struct processors all_cores[] =
       ISA_ARMv8m_base,
       isa_nobit
     },
+    NULL,
     &arm_v6m_tune
   },
   {
@@ -1215,12 +1355,78 @@ static const struct processors all_cores[] =
     (TF_LDSCHED),
     "8M_MAIN", BASE_ARCH_8M_MAIN,
     {
-      ISA_ARMv8m_main,isa_bit_ARMv7em,
+      ISA_ARMv8m_main,
+      isa_bit_ARMv7em,
       isa_nobit
     },
+    NULL,
     &arm_v7m_tune
   },
-  {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0, {isa_nobit}, NULL}
+  {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0, {isa_nobit}, NULL, NULL}
+};
+
+static const struct cpu_option arch_opttab_armv8_a[] = {
+  {
+    "crc", false,
+    { isa_bit_crc32, isa_nobit }
+  },
+  {
+    "simd", false,
+    { ISA_FP_ARMv8,ISA_NEON, isa_nobit }
+  },
+  {
+    "crypto", false,
+    { ISA_FP_ARMv8,ISA_NEON,ISA_CRYPTO, isa_nobit }
+  },
+  {
+    "nofp", true,
+    { ISA_FP_ARMv8,ISA_NEON,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, {isa_nobit}}
+};
+
+static const struct cpu_option arch_opttab_armv8_1_a[] = {
+  {
+    "simd", false,
+    { ISA_FP_ARMv8,ISA_NEON, isa_nobit }
+  },
+  {
+    "crypto", false,
+    { ISA_FP_ARMv8,ISA_NEON,ISA_CRYPTO, isa_nobit }
+  },
+  {
+    "nofp", true,
+    { ISA_FP_ARMv8,ISA_NEON,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, {isa_nobit}}
+};
+
+static const struct cpu_option arch_opttab_armv8_2_a[] = {
+  {
+    "fp16", false,
+    { isa_bit_fp16,ISA_FP_ARMv8,ISA_NEON, isa_nobit }
+  },
+  {
+    "simd", false,
+    { ISA_FP_ARMv8,ISA_NEON, isa_nobit }
+  },
+  {
+    "crypto", false,
+    { ISA_FP_ARMv8,ISA_NEON,ISA_CRYPTO, isa_nobit }
+  },
+  {
+    "nofp", true,
+    { isa_bit_fp16,ISA_FP_ARMv8,ISA_NEON,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, {isa_nobit}}
+};
+
+static const struct cpu_option arch_opttab_armv8_m_main[] = {
+  {
+    "dsp", false,
+    { isa_bit_ARMv7em, isa_nobit }
+  },
+  { NULL, false, {isa_nobit}}
 };
 
 static const struct processors all_architectures[] =
@@ -1233,6 +1439,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv2,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1243,6 +1450,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv2,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1253,6 +1461,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1263,6 +1472,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv3m,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1273,6 +1483,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv4,isa_bit_mode26,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1283,6 +1494,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv4t,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1293,6 +1505,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv5,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1303,6 +1516,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv5t,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1313,6 +1527,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv5e,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1323,6 +1538,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv5te,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1333,6 +1549,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv5tej,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1343,6 +1560,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv6,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1353,6 +1571,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv6j,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1363,6 +1582,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv6k,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1373,6 +1593,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv6z,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1383,6 +1604,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv6kz,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1393,6 +1615,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv6kz,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1403,6 +1626,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv6t2,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1413,6 +1637,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv6m,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1423,6 +1648,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv6m,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1433,6 +1659,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv7,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1443,6 +1670,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv7a,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1453,6 +1681,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv7ve,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1463,6 +1692,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv7r,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1473,6 +1703,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv7m,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1483,6 +1714,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv7em,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1493,16 +1725,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv8a,
       isa_nobit
     },
-    NULL
-  },
-  {
-    "armv8-a+crc", TARGET_CPU_cortexa53,
-    (TF_CO_PROC),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    arch_opttab_armv8_a,
     NULL
   },
   {
@@ -1513,6 +1736,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv8_1a,
       isa_nobit
     },
+    arch_opttab_armv8_1_a,
     NULL
   },
   {
@@ -1523,16 +1747,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv8_2a,
       isa_nobit
     },
-    NULL
-  },
-  {
-    "armv8.2-a+fp16", TARGET_CPU_cortexa53,
-    (TF_CO_PROC),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8_2a,isa_bit_fp16,
-      isa_nobit
-    },
+    arch_opttab_armv8_2_a,
     NULL
   },
   {
@@ -1543,6 +1758,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv8m_base,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1553,16 +1769,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv8m_main,
       isa_nobit
     },
-    NULL
-  },
-  {
-    "armv8-m.main+dsp", TARGET_CPU_cortexm33,
-    (TF_CO_PROC),
-    "8M_MAIN", BASE_ARCH_8M_MAIN,
-    {
-      ISA_ARMv8m_main,isa_bit_ARMv7em,
-      isa_nobit
-    },
+    arch_opttab_armv8_m_main,
     NULL
   },
   {
@@ -1573,6 +1780,7 @@ static const struct processors all_architectures[] =
       ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,
       isa_nobit
     },
+    NULL,
     NULL
   },
   {
@@ -1583,9 +1791,10 @@ static const struct processors all_architectures[] =
       ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,isa_bit_iwmmxt2,
       isa_nobit
     },
+    NULL,
     NULL
   },
-  {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0, {isa_nobit}, NULL}
+  {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0, {isa_nobit}, NULL, NULL}
 };
 
 const struct arm_fpu_desc all_fpus[] =
index 1100f3a5411ad4d324862b823e77d96a3baa5dad..6c9346cc9adc454a1941aa648a1683453062a3bd 100644 (file)
@@ -237,20 +237,20 @@ begin arch armv8-a
  tune flags CO_PROC
  base 8A
  isa ARMv8a
+ option crc add bit_crc32
+ option simd add FP_ARMv8 NEON
+ option crypto add FP_ARMv8 NEON CRYPTO
+ option nofp remove FP_ARMv8 NEON CRYPTO
 end arch armv8-a
 
-begin arch armv8-a+crc
- tune for cortex-a53
- tune flags CO_PROC
- base 8A
- isa ARMv8a bit_crc32
-end arch armv8-a+crc
-
 begin arch armv8.1-a
  tune for cortex-a53
  tune flags CO_PROC
  base 8A
  isa ARMv8_1a
+ option simd add FP_ARMv8 NEON
+ option crypto add FP_ARMv8 NEON CRYPTO
+ option nofp remove FP_ARMv8 NEON CRYPTO
 end arch armv8.1-a
 
 begin arch armv8.2-a
@@ -258,15 +258,12 @@ begin arch armv8.2-a
  tune flags CO_PROC
  base 8A
  isa ARMv8_2a
+ option fp16 add bit_fp16 FP_ARMv8 NEON
+ option simd add FP_ARMv8 NEON
+ option crypto add FP_ARMv8 NEON CRYPTO
+ option nofp remove bit_fp16 FP_ARMv8 NEON CRYPTO
 end arch armv8.2-a
 
-begin arch armv8.2-a+fp16
- tune for cortex-a53
- tune flags CO_PROC
- base 8A
- isa ARMv8_2a bit_fp16
-end arch armv8.2-a+fp16
-
 begin arch armv8-m.base
  tune for cortex-m23
  base 8M_BASE
@@ -278,15 +275,9 @@ begin arch armv8-m.main
  tune flags CO_PROC
  base 8M_MAIN
  isa ARMv8m_main
+ option dsp add bit_ARMv7em
 end arch armv8-m.main
 
-begin arch armv8-m.main+dsp
- tune for cortex-m33
- tune flags CO_PROC
- base 8M_MAIN
- isa ARMv8m_main bit_ARMv7em
-end arch armv8-m.main+dsp
-
 begin arch iwmmxt
  tune for iwmmxt
  tune flags LDSCHED STRONG XSCALE
@@ -310,6 +301,7 @@ end arch iwmmxt2
 #   architecture <name>
 #   [fpu <name>]
 #   [isa <additional-isa-flags-list>]
+#   [option <name> add|remove <isa-list>]*
 #   [costs <name>]
 # end cpu <name>
 #
@@ -847,6 +839,8 @@ begin cpu cortex-a8
  cname cortexa8
  tune flags LDSCHED
  architecture armv7-a
+ fpu neon-vfpv3
+ option nofp remove NEON VFPv3
  costs cortex_a8
 end cpu cortex-a8
 
@@ -854,6 +848,9 @@ begin cpu cortex-a9
  cname cortexa9
  tune flags LDSCHED
  architecture armv7-a
+ fpu neon-vfpv3
+ option nofp remove NEON VFPv3
+ option nosimd remove NEON
  costs cortex_a9
 end cpu cortex-a9
 
index cb45e097c90b7d88b23e9e4746b0a6ac48420f9c..0f50c64f4b1239191d9d178f78249537b288a73d 100644 (file)
@@ -434,31 +434,22 @@ EnumValue
 Enum(arm_arch) String(armv8-a) Value(26)
 
 EnumValue
-Enum(arm_arch) String(armv8-a+crc) Value(27)
+Enum(arm_arch) String(armv8.1-a) Value(27)
 
 EnumValue
-Enum(arm_arch) String(armv8.1-a) Value(28)
+Enum(arm_arch) String(armv8.2-a) Value(28)
 
 EnumValue
-Enum(arm_arch) String(armv8.2-a) Value(29)
+Enum(arm_arch) String(armv8-m.base) Value(29)
 
 EnumValue
-Enum(arm_arch) String(armv8.2-a+fp16) Value(30)
+Enum(arm_arch) String(armv8-m.main) Value(30)
 
 EnumValue
-Enum(arm_arch) String(armv8-m.base) Value(31)
+Enum(arm_arch) String(iwmmxt) Value(31)
 
 EnumValue
-Enum(arm_arch) String(armv8-m.main) Value(32)
-
-EnumValue
-Enum(arm_arch) String(armv8-m.main+dsp) Value(33)
-
-EnumValue
-Enum(arm_arch) String(iwmmxt) Value(34)
-
-EnumValue
-Enum(arm_arch) String(iwmmxt2) Value(35)
+Enum(arm_arch) String(iwmmxt2) Value(32)
 
 Enum
 Name(arm_fpu) Type(enum fpu_type)
index 2502eb8f3a685816051b82b957f753ec3e23441b..f35a1c2fc1bcd5321fb256b55b48d9d310a02ee0 100644 (file)
@@ -975,6 +975,13 @@ int arm_regs_in_sequence[] =
 \f
 /* Initialization code.  */
 
+struct cpu_option
+{
+  const char *const name;
+  bool remove;
+  const enum isa_feature isa_bits[isa_num_bits];
+};
+
 struct processors
 {
   const char *const name;
@@ -982,7 +989,8 @@ struct processors
   unsigned int tune_flags;
   const char *arch;
   enum base_architecture base_arch;
-  enum isa_feature isa_bits[isa_num_bits];
+  const enum isa_feature isa_bits[isa_num_bits];
+  const struct cpu_option* const opttab;
   const struct tune_params *const tune;
 };
 
@@ -3068,9 +3076,13 @@ arm_parse_arch_cpu_name (const struct processors *list, const char *optname,
                         const char *target)
 {
   const struct processors *entry;
+  const char *end  = strchr (target, '+');
+  size_t len = end ? end - target : strlen (target);
+
   for (entry = list; entry->name != NULL; entry++)
     {
-      if (streq (entry->name, target))
+      if (strncmp (entry->name, target, len) == 0
+         && entry->name[len] == '\0')
        return entry;
     }
 
@@ -3079,6 +3091,92 @@ arm_parse_arch_cpu_name (const struct processors *list, const char *optname,
   return NULL;
 }
 
+/* OPT isn't a recognized feature.  Print a suitable error message and
+   suggest a possible value.  Always print the list of permitted
+   values.  */
+static void
+arm_unrecognized_feature (const char *opt, size_t len,
+                         const struct processors *target)
+{
+  char *this_opt = XALLOCAVEC (char, len+1);
+  auto_vec<const char*> candidates;
+
+  strncpy (this_opt, opt, len);
+  this_opt[len] = 0;
+
+  error_at (input_location, "%qs does not support feature %qs", target->name,
+           this_opt);
+  for (const cpu_option *list = target->opttab; list->name != NULL; list++)
+    candidates.safe_push (list->name);
+
+  char *s;
+  const char *hint = candidates_list_and_hint (this_opt, s, candidates);
+
+  if (hint)
+    inform (input_location, "valid feature names are: %s; did you mean %qs?",
+           s, hint);
+  else
+    inform (input_location, "valid feature names are: %s", s);
+
+  XDELETEVEC (s);
+}
+
+/* Parse any feature extensions to add to (or remove from) the
+   permitted ISA selection.  */
+static void
+arm_parse_arch_cpu_features (sbitmap isa, const struct processors *target,
+                            const char *opts_in)
+{
+  const char *opts = opts_in;
+
+  if (!opts)
+    return;
+
+  if (!target->opttab)
+    {
+      error_at (input_location, "%s does not take any feature options",
+               target->name);
+      return;
+    }
+
+  while (opts)
+    {
+      gcc_assert (*opts == '+');
+      const struct cpu_option *entry;
+      const char *end = strchr (++opts, '+');
+      size_t len = end ? end - opts : strlen (opts);
+      bool matched = false;
+
+      for (entry = target->opttab; !matched && entry->name != NULL; entry++)
+       {
+         if (strncmp (entry->name, opts, len) == 0
+             && entry->name[len] == '\0')
+           {
+             if (isa)
+               {
+                 const enum isa_feature *f = entry->isa_bits;
+                 if (entry->remove)
+                   {
+                     while (*f != isa_nobit)
+                       bitmap_clear_bit (isa, *(f++));
+                   }
+                 else
+                   {
+                     while (*f != isa_nobit)
+                       bitmap_set_bit (isa, *(f++));
+                   }
+               }
+             matched = true;
+           }
+       }
+
+      if (!matched)
+       arm_unrecognized_feature (opts, len, target);
+
+      opts = end;
+    }
+}
+
 static sbitmap isa_all_fpubits;
 static sbitmap isa_quirkbits;
 
@@ -3095,35 +3193,50 @@ arm_configure_build_target (struct arm_build_target *target,
   const struct processors *arm_selected_arch = NULL;
   const struct processors *arm_selected_cpu = NULL;
   const struct arm_fpu_desc *arm_selected_fpu = NULL;
+  const char *tune_opts = NULL;
+  const char *arch_opts = NULL;
+  const char *cpu_opts = NULL;
 
   bitmap_clear (target->isa);
   target->core_name = NULL;
   target->arch_name = NULL;
 
   if (opts_set->x_arm_arch_string)
-    arm_selected_arch = arm_parse_arch_cpu_name (all_architectures,
-                                                "-march",
-                                                opts->x_arm_arch_string);
+    {
+      arm_selected_arch = arm_parse_arch_cpu_name (all_architectures,
+                                                  "-march",
+                                                  opts->x_arm_arch_string);
+      arch_opts = strchr (opts->x_arm_arch_string, '+');
+    }
+
   if (opts_set->x_arm_cpu_string)
     {
       arm_selected_cpu = arm_parse_arch_cpu_name (all_cores, "-mcpu",
                                                  opts->x_arm_cpu_string);
+      cpu_opts = strchr (opts->x_arm_cpu_string, '+');
       arm_selected_tune = arm_selected_cpu;
+      /* If taking the tuning from -mcpu, we don't need to rescan the
+        options for tuning.  */
     }
 
   if (opts_set->x_arm_tune_string)
-    arm_selected_tune = arm_parse_arch_cpu_name (all_cores, "-mtune",
-                                                opts->x_arm_tune_string);
+    {
+      arm_selected_tune = arm_parse_arch_cpu_name (all_cores, "-mtune",
+                                                  opts->x_arm_tune_string);
+      tune_opts = strchr (opts->x_arm_tune_string, '+');
+    }
 
   if (arm_selected_arch)
     {
       arm_initialize_isa (target->isa, arm_selected_arch->isa_bits);
+      arm_parse_arch_cpu_features (target->isa, arm_selected_arch, arch_opts);
 
       if (arm_selected_cpu)
        {
          auto_sbitmap cpu_isa (isa_num_bits);
 
          arm_initialize_isa (cpu_isa, arm_selected_cpu->isa_bits);
+         arm_parse_arch_cpu_features (cpu_isa, arm_selected_cpu, cpu_opts);
          bitmap_xor (cpu_isa, cpu_isa, target->isa);
          /* Ignore any bits that are quirk bits.  */
          bitmap_and_compl (cpu_isa, cpu_isa, isa_quirkbits);
@@ -3163,6 +3276,7 @@ arm_configure_build_target (struct arm_build_target *target,
     {
       target->core_name = arm_selected_cpu->name;
       arm_initialize_isa (target->isa, arm_selected_cpu->isa_bits);
+      arm_parse_arch_cpu_features (target->isa, arm_selected_cpu, cpu_opts);
     }
   /* If the user did not specify a processor, choose one for them.  */
   else
@@ -3283,14 +3397,12 @@ arm_configure_build_target (struct arm_build_target *target,
       bitmap_and_compl (target->isa, target->isa, isa_all_fpubits);
       bitmap_ior (target->isa, target->isa, fpu_bits);
     }
-  else if (target->core_name == NULL)
-    /* To support this we need to be able to parse FPU feature options
-       from the architecture string.  */
-    sorry ("-mfpu=auto not currently supported without an explicit CPU.");
 
   /* The selected cpu may be an architecture, so lookup tuning by core ID.  */
   if (!arm_selected_tune)
     arm_selected_tune = &all_cores[arm_selected_cpu->core];
+  else /* Validate the features passed to -mtune.  */
+    arm_parse_arch_cpu_features (NULL, arm_selected_tune, tune_opts);
 
   /* Finish initializing the target structure.  */
   target->arch_pp_name = arm_selected_cpu->arch;
@@ -26165,6 +26277,39 @@ arm_print_tune_info (void)
               (int) current_tune->sched_autopref);
 }
 
+/* Print .arch and .arch_extension directives corresponding to the
+   current architecture configuration.  */
+static void
+arm_print_asm_arch_directives ()
+{
+  const struct processors *arch
+    = arm_parse_arch_cpu_name (all_architectures, "-march",
+                              arm_active_target.arch_name);
+  auto_sbitmap opt_bits (isa_num_bits);
+
+  gcc_assert (arch);
+
+  asm_fprintf (asm_out_file, "\t.arch %s\n", arm_active_target.arch_name);
+  if (!arch->opttab)
+    return;
+
+  for (const struct cpu_option *opt = arch->opttab; opt->name != NULL; opt++)
+    {
+      if (!opt->remove)
+       {
+         arm_initialize_isa (opt_bits, opt->isa_bits);
+
+         /* If every feature bit of this option is set in the target
+            ISA specification, print out the option name.  However,
+            don't print anything if all the bits are part of the
+            FPU specification.  */
+         if (bitmap_subset_p (opt_bits, arm_active_target.isa)
+             && !bitmap_subset_p (opt_bits, isa_all_fpubits))
+           asm_fprintf (asm_out_file, "\t.arch_extension %s\n", opt->name);
+       }
+    }
+}
+
 static void
 arm_file_start (void)
 {
@@ -26179,7 +26324,7 @@ arm_file_start (void)
         assembler would not need to know about all new CPU names as
         they are added.  */
       if (!arm_active_target.core_name)
-        {
+       {
          /* armv7ve doesn't support any extensions.  */
          if (strcmp (arm_active_target.arch_name, "armv7ve") == 0)
            {
@@ -26192,24 +26337,8 @@ arm_file_start (void)
              asm_fprintf (asm_out_file, "\t.arch_extension mp\n");
            }
          else
-           {
-             const char* pos = strchr (arm_active_target.arch_name, '+');
-             if (pos)
-               {
-                 char buf[32];
-                 gcc_assert (strlen (arm_active_target.arch_name)
-                             <= sizeof (buf) / sizeof (*pos));
-                 strncpy (buf, arm_active_target.arch_name,
-                          (pos - arm_active_target.arch_name) * sizeof (*pos));
-                 buf[pos - arm_active_target.arch_name] = '\0';
-                 asm_fprintf (asm_out_file, "\t.arch %s\n", buf);
-                 asm_fprintf (asm_out_file, "\t.arch_extension %s\n", pos + 1);
-               }
-             else
-               asm_fprintf (asm_out_file, "\t.arch %s\n",
-                            arm_active_target.arch_name);
-           }
-        }
+           arm_print_asm_arch_directives ();
+       }
       else if (strncmp (arm_active_target.core_name, "generic", 7) == 0)
        asm_fprintf (asm_out_file, "\t.arch %s\n",
                     arm_active_target.core_name + 8);
@@ -26233,7 +26362,7 @@ arm_file_start (void)
        }
 
       /* Some of these attributes only apply when the corresponding features
-         are used.  However we don't have any easy way of figuring this out.
+        are used.  However we don't have any easy way of figuring this out.
         Conservatively record the setting that would have been used.  */
 
       if (flag_rounding_math)
index dac11a009eee4eb6dd6a28b2eef8a7956fcc1beb..c95d9228a3e531b7d332dfd543e85e085515bdef 100644 (file)
@@ -117,11 +117,28 @@ function gen_headers () {
 function gen_data () {
     boilerplate("C")
 
+    ncpus = split (cpu_list, cpus)
+
+    for (n = 1; n <= ncpus; n++) {
+       if (cpus[n] in cpu_opts) {
+           print "static const struct cpu_option cpu_opttab_" \
+               cpu_cnames[cpus[n]] "[] = {"
+           nopts = split (cpu_opts[cpus[n]], opts)
+           for (opt = 1; opt <= nopts; opt++) {
+               print "  {"
+               print "    \"" opts[opt] "\", " \
+                   cpu_opt_remove[cpus[n],opts[opt]] ","
+               print "    { " cpu_opt_isa[cpus[n],opts[opt]] ", isa_nobit }"
+               print "  },"
+           }
+           print "  { NULL, false, {isa_nobit}}"
+           print "};\n"
+       }
+    }
+
     print "static const struct processors all_cores[] ="
     print "{"
 
-    ncpus = split (cpu_list, cpus)
-
     for (n = 1; n <= ncpus; n++) {
        print "  {"
        print "    \"" cpus[n] "\","
@@ -137,30 +154,60 @@ function gen_data () {
        if (cpus[n] in cpu_tune_flags) {
            print "    (" cpu_tune_flags[cpus[n]] "),"
        } else print "    0,"
-       if (! (cpu_arch[cpus[n]] in arch_isa)) {
-           fatal("unknown arch " cpu_arch[cpus[n]] " for cpu " cpus[n])
+       nfeats = split (cpu_arch[cpus[n]], feats, "+")
+       if (! (feats[1] in arch_isa)) {
+           fatal("unknown arch " feats[1] " for cpu " cpus[n])
        }
-       print "    \"" arch_base[cpu_arch[cpus[n]]] "\", BASE_ARCH_" \
-           arch_base[cpu_arch[cpus[n]]] ","
+       print "    \"" arch_base[feats[1]] "\", BASE_ARCH_" \
+           arch_base[feats[1]] ","
        print "    {"
-       print "      " arch_isa[cpu_arch[cpus[n]]] ","
+       print "      " arch_isa[feats[1]] ","
+       for (m = 2; m <= nfeats; m++) {
+           if (! ((feats[1], feats[m]) in arch_opt_isa)) {
+               fatal("unknown feature " feats[m] " for architecture " feats[1])
+           }
+           if (arch_opt_remove[feats[1],feats[m]] == "true") {
+               fatal("cannot remove features from architecture specs")
+           }
+           print "      " arch_opt_isa[feats[1],feats[m]] ","
+       }
        if (cpus[n] in cpu_fpu) print "      " fpu_isa[cpu_fpu[cpus[n]]] ","
        if (cpus[n] in cpu_isa) print "      " cpu_isa[cpus[n]] ","
        print "      isa_nobit"
        print "    },"
+       if (cpus[n] in cpu_opts) {
+           print "    cpu_opttab_" cpu_cnames[cpus[n]] ","
+       } else print "    NULL,"
        print "    &arm_" cpu_cost[cpus[n]] "_tune"
        print "  },"
     }
 
     print "  {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0," \
-       " {isa_nobit}, NULL}"
+       " {isa_nobit}, NULL, NULL}"
     print "};\n"
 
+    narchs = split (arch_list, archs)
+
+    for (n = 1; n <= narchs; n++) {
+       if (archs[n] in arch_opts) {
+           print "static const struct cpu_option arch_opttab_" \
+               arch_cnames[archs[n]] "[] = {"
+           nopts = split (arch_opts[archs[n]], opts)
+           for (opt = 1; opt <= nopts; opt++) {
+               print "  {"
+               print "    \"" opts[opt] "\", " \
+                   arch_opt_remove[archs[n],opts[opt]] ","
+               print "    { " arch_opt_isa[archs[n],opts[opt]] ", isa_nobit }"
+               print "  },"
+           }
+           print "  { NULL, false, {isa_nobit}}"
+           print "};\n"
+       }
+    }
+
     print "static const struct processors all_architectures[] ="
     print "{"
 
-    narchs = split (arch_list, archs)
-
     for (n = 1; n <= narchs; n++) {
        print "  {"
        if (! (arch_tune_for[archs[n]] in cpu_cnames)) {
@@ -178,12 +225,15 @@ function gen_data () {
        print "      " arch_isa[archs[n]] ","
        print "      isa_nobit"
        print "    },"
+       if (archs[n] in arch_opts) {
+           print "    arch_opttab_" arch_cnames[archs[n]] ","
+       } else print "    NULL,"
        print "    NULL"
        print "  },"
     }
 
     print "  {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0," \
-       " {isa_nobit}, NULL}"
+       " {isa_nobit}, NULL, NULL}"
     print "};\n"
 
     print "const struct arm_fpu_desc all_fpus[] ="
@@ -215,11 +265,15 @@ function gen_comm_data () {
     for (n = 1; n <= ncpus; n++) {
        print "  {"
        print "    \"" cpus[n] "\","
-       if (! (cpu_arch[cpus[n]] in arch_isa)) {
-           fatal("unknown arch " cpu_arch[cpus[n]] " for cpu " cpus[n])
+       # Just truncate the architecture name at the beginning of the
+       # extensions.  We don't need any of those here (at present).
+       arch_name = cpu_arch[cpus[n]];
+       sub("+.*", "", arch_name)
+       if (! (arch_name in arch_isa)) {
+           fatal("unknown arch " arch_name " for cpu " cpus[n])
        }
        print "    {"
-       print "      " arch_isa[cpu_arch[cpus[n]]] ","
+       print "      " arch_isa[arch_name] ","
        if (cpus[n] in cpu_fpu) print "      " fpu_isa[cpu_fpu[cpus[n]]] ","
        if (cpus[n] in cpu_isa) print "      " cpu_isa[cpus[n]] ","
        print "      isa_nobit"
@@ -382,6 +436,8 @@ BEGIN {
        fatal("arch definition lacks an \"isa\" statement")
     }
     arch_list = arch_list " " arch_name
+    arch_cnames[arch_name] = arch_name
+    gsub(/[-+.]/, "_", arch_cnames[arch_name])
     arch_name = ""
     parse_ok = 1
 }
@@ -453,6 +509,32 @@ BEGIN {
     parse_ok = 1
 }
 
+/^[    ]*option / {
+    name=$2
+    if ($3 == "add") {
+       remove = "false"
+    } else if ($3 == "remove") {
+       remove = "true"
+    } else fatal("syntax: option <name> add|remove isa-list")
+    flags=""
+    flag_count = NF
+    for (n = 4; n <= flag_count; n++) {
+       if (n == 4) {
+           flags = isa_pfx($n)
+       } else flags = flags "," isa_pfx($n)
+    }
+    if (cpu_name != "") {
+       cpu_opts[cpu_name] = cpu_opts[cpu_name] " " name
+       cpu_opt_remove[cpu_name,name] = remove
+       cpu_opt_isa[cpu_name,name] = flags
+    } else if (arch_name != "") {
+       arch_opts[arch_name] = arch_opts[arch_name] " " name
+       arch_opt_remove[arch_name,name] = remove
+       arch_opt_isa[arch_name,name] = flags
+    } else fatal("\"option\" outside of cpu or arch block")
+    parse_ok = 1
+}
+
 /^[    ]*costs / {
     if (cpu_name == "") fatal("\"costs\" outside of cpu block")
     cpu_cost[cpu_name] = $2