[ARM] Separate extensions from architectures in arm_cpus
authorThomas Preud'homme <thomas.preudhomme@arm.com>
Wed, 21 Jun 2017 12:16:56 +0000 (13:16 +0100)
committerThomas Preud'homme <thomas.preudhomme@arm.com>
Wed, 21 Jun 2017 13:11:14 +0000 (14:11 +0100)
=== Context ===

This patch is part of a patch series to add support for ARMv8-R
architecture. Its purpose is to distinguish for a CPU the feature bits
coming from its architecture from the feature bits coming from
extension(s) available in this CPU.

=== Motivation ===

This distinction is necessary to allow the Tag_CPU_arch build attribute
value to be exactly as per the architecture of the selected CPU. With
mixed architecture and extension feature bit, it is impossible to find
an architecture with an exact match of feature bit and the build
attribute value logic must then select the closest match which might not
be the right architecture.

=== Patch description ===

The patch creates a new field in the arm_cpus table to hold the feature
set for the extensions available in each CPU. The existing architecture
feature set is then updated to remove those feature bit. The patch also
takes advantage of all the lines being changed to reindent the whole
table.

Note: This patch *adds* a memory leak due to mcpu_cpu_opt sometimes
pointing to dynamically allocated feature bits which is never freeed.
The subsequent patch in the series solves this issue as well as a
preexisting identical issue in arm_parse_extension. The patches are kept
separate for ease of review since they are both big enough already.

2017-06-21  Thomas Preud'homme  <thomas.preudhomme@arm.com>

gas/
* config/tc-arm.c (struct arm_cpu_option_table): New ext field.
(ARM_CPU_OPT): Add parameter to set new ext field and reorder canonical
name field just after the name field.
(arm_cpus): Move extension feature bit from value field to ext field,
reorder parameter according to changes in ARM_CPU_OPT and reindent.
(arm_parse_cpu): Point mcpu_cpu_opt to a bitfield merging the value and
ext field from the selected arm_cpus entry.
(s_arm_cpu): Likewise.

gas/ChangeLog
gas/config/tc-arm.c

index 2e7e1852894186bc30d5523095f86fa1984353d1..d85e1d42b1d65933db68f1ffaa7fd9a2dc2a01f6 100644 (file)
@@ -1,3 +1,14 @@
+2017-06-21  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+
+       * config/tc-arm.c (struct arm_cpu_option_table): New ext field.
+       (ARM_CPU_OPT): Add parameter to set new ext field and reorder canonical
+       name field just after the name field.
+       (arm_cpus): Move extension feature bit from value field to ext field,
+       reorder parameter according to changes in ARM_CPU_OPT and reindent.
+       (arm_parse_cpu): Point mcpu_cpu_opt to a bitfield merging the value and
+       ext field from the selected arm_cpus entry.
+       (s_arm_cpu): Likewise.
+
 2017-06-21  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * config/tc-aarch64.c (aarch64_cpus): Add cortex-a55 and cortex-a75.
index 8e8fea638f5718e9d05e02767f7ee39b24d66b99..ca458d440114cdab4e8ffea198608a93269a1b1a 100644 (file)
@@ -25457,6 +25457,7 @@ struct arm_cpu_option_table
   const char *name;
   size_t name_len;
   const arm_feature_set        value;
+  const arm_feature_set        ext;
   /* For some CPUs we assume an FPU unless the user explicitly sets
      -mfpu=... */
   const arm_feature_set        default_fpu;
@@ -25467,175 +25468,378 @@ struct arm_cpu_option_table
 
 /* This list should, at a minimum, contain all the cpu names
    recognized by GCC.  */
-#define ARM_CPU_OPT(N, V, DF, CN) { N, sizeof (N) - 1, V, DF, CN }
+#define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN }
 static const struct arm_cpu_option_table arm_cpus[] =
 {
-  ARM_CPU_OPT ("all",          ARM_ANY,         FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm1",         ARM_ARCH_V1,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm2",         ARM_ARCH_V2,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm250",       ARM_ARCH_V2S,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm3",         ARM_ARCH_V2S,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm6",         ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm60",                ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm600",       ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm610",       ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm620",       ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm7",         ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm7m",                ARM_ARCH_V3M,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm7d",                ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm7dm",       ARM_ARCH_V3M,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm7di",       ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm7dmi",      ARM_ARCH_V3M,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm70",                ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm700",       ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm700i",      ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm710",       ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm710t",      ARM_ARCH_V4T,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm720",       ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm720t",      ARM_ARCH_V4T,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm740t",      ARM_ARCH_V4T,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm710c",      ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm7100",      ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm7500",      ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm7500fe",    ARM_ARCH_V3,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm7t",                ARM_ARCH_V4T,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm7tdmi",     ARM_ARCH_V4T,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm7tdmi-s",   ARM_ARCH_V4T,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm8",         ARM_ARCH_V4,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm810",       ARM_ARCH_V4,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("strongarm",    ARM_ARCH_V4,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("strongarm1",   ARM_ARCH_V4,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("strongarm110", ARM_ARCH_V4,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("strongarm1100",        ARM_ARCH_V4,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("strongarm1110",        ARM_ARCH_V4,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm9",         ARM_ARCH_V4T,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm920",       ARM_ARCH_V4T,    FPU_ARCH_FPA,    "ARM920T"),
-  ARM_CPU_OPT ("arm920t",      ARM_ARCH_V4T,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm922t",      ARM_ARCH_V4T,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm940t",      ARM_ARCH_V4T,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("arm9tdmi",     ARM_ARCH_V4T,    FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("fa526",                ARM_ARCH_V4,     FPU_ARCH_FPA,    NULL),
-  ARM_CPU_OPT ("fa626",                ARM_ARCH_V4,     FPU_ARCH_FPA,    NULL),
+  ARM_CPU_OPT ("all",            NULL,                ARM_ANY,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm1",           NULL,                ARM_ARCH_V1,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm2",           NULL,                ARM_ARCH_V2,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm250",         NULL,                ARM_ARCH_V2S,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm3",           NULL,                ARM_ARCH_V2S,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm6",           NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm60",                  NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm600",         NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm610",         NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm620",         NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm7",           NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm7m",                  NULL,                ARM_ARCH_V3M,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm7d",                  NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm7dm",         NULL,                ARM_ARCH_V3M,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm7di",         NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm7dmi",        NULL,                ARM_ARCH_V3M,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm70",                  NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm700",         NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm700i",        NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm710",         NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm710t",        NULL,                ARM_ARCH_V4T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm720",         NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm720t",        NULL,                ARM_ARCH_V4T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm740t",        NULL,                ARM_ARCH_V4T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm710c",        NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm7100",        NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm7500",        NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm7500fe",      NULL,                ARM_ARCH_V3,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm7t",                  NULL,                ARM_ARCH_V4T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm7tdmi",       NULL,                ARM_ARCH_V4T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm7tdmi-s",     NULL,                ARM_ARCH_V4T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm8",           NULL,                ARM_ARCH_V4,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm810",         NULL,                ARM_ARCH_V4,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("strongarm",      NULL,                ARM_ARCH_V4,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("strongarm1",     NULL,                ARM_ARCH_V4,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("strongarm110",   NULL,                ARM_ARCH_V4,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("strongarm1100",          NULL,                ARM_ARCH_V4,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("strongarm1110",          NULL,                ARM_ARCH_V4,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm9",           NULL,                ARM_ARCH_V4T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm920",         "ARM920T",           ARM_ARCH_V4T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm920t",        NULL,                ARM_ARCH_V4T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm922t",        NULL,                ARM_ARCH_V4T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm940t",        NULL,                ARM_ARCH_V4T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("arm9tdmi",       NULL,                ARM_ARCH_V4T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("fa526",                  NULL,                ARM_ARCH_V4,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+  ARM_CPU_OPT ("fa626",                  NULL,                ARM_ARCH_V4,
+              ARM_ARCH_NONE,
+              FPU_ARCH_FPA),
+
   /* For V5 or later processors we default to using VFP; but the user
      should really set the FPU type explicitly.         */
-  ARM_CPU_OPT ("arm9e-r0",     ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("arm9e",                ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("arm926ej",     ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2, "ARM926EJ-S"),
-  ARM_CPU_OPT ("arm926ejs",    ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2, "ARM926EJ-S"),
-  ARM_CPU_OPT ("arm926ej-s",   ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("arm946e-r0",   ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("arm946e",      ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, "ARM946E-S"),
-  ARM_CPU_OPT ("arm946e-s",    ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("arm966e-r0",   ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("arm966e",      ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, "ARM966E-S"),
-  ARM_CPU_OPT ("arm966e-s",    ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("arm968e-s",    ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("arm10t",       ARM_ARCH_V5T,    FPU_ARCH_VFP_V1, NULL),
-  ARM_CPU_OPT ("arm10tdmi",    ARM_ARCH_V5T,    FPU_ARCH_VFP_V1, NULL),
-  ARM_CPU_OPT ("arm10e",       ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("arm1020",      ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, "ARM1020E"),
-  ARM_CPU_OPT ("arm1020t",     ARM_ARCH_V5T,    FPU_ARCH_VFP_V1, NULL),
-  ARM_CPU_OPT ("arm1020e",     ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("arm1022e",     ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("arm1026ejs",   ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2,
-                                                                "ARM1026EJ-S"),
-  ARM_CPU_OPT ("arm1026ej-s",  ARM_ARCH_V5TEJ,  FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("fa606te",      ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("fa616te",      ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("fa626te",      ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("fmp626",       ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("fa726te",      ARM_ARCH_V5TE,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("arm1136js",    ARM_ARCH_V6,     FPU_NONE,        "ARM1136J-S"),
-  ARM_CPU_OPT ("arm1136j-s",   ARM_ARCH_V6,     FPU_NONE,        NULL),
-  ARM_CPU_OPT ("arm1136jfs",   ARM_ARCH_V6,     FPU_ARCH_VFP_V2,
-                                                                "ARM1136JF-S"),
-  ARM_CPU_OPT ("arm1136jf-s",  ARM_ARCH_V6,     FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("mpcore",       ARM_ARCH_V6K,    FPU_ARCH_VFP_V2, "MPCore"),
-  ARM_CPU_OPT ("mpcorenovfp",  ARM_ARCH_V6K,    FPU_NONE,        "MPCore"),
-  ARM_CPU_OPT ("arm1156t2-s",  ARM_ARCH_V6T2,   FPU_NONE,        NULL),
-  ARM_CPU_OPT ("arm1156t2f-s", ARM_ARCH_V6T2,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("arm1176jz-s",  ARM_ARCH_V6KZ,   FPU_NONE,        NULL),
-  ARM_CPU_OPT ("arm1176jzf-s", ARM_ARCH_V6KZ,   FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("cortex-a5",    ARM_ARCH_V7A_MP_SEC,
-                                                FPU_NONE,        "Cortex-A5"),
-  ARM_CPU_OPT ("cortex-a7",    ARM_ARCH_V7VE,   FPU_ARCH_NEON_VFP_V4,
-                                                                 "Cortex-A7"),
-  ARM_CPU_OPT ("cortex-a8",    ARM_ARCH_V7A_SEC,
-                                                ARM_FEATURE_COPROC (FPU_VFP_V3
-                                                       | FPU_NEON_EXT_V1),
-                                                                 "Cortex-A8"),
-  ARM_CPU_OPT ("cortex-a9",    ARM_ARCH_V7A_MP_SEC,
-                                                ARM_FEATURE_COPROC (FPU_VFP_V3
-                                                       | FPU_NEON_EXT_V1),
-                                                                 "Cortex-A9"),
-  ARM_CPU_OPT ("cortex-a12",   ARM_ARCH_V7VE,   FPU_ARCH_NEON_VFP_V4,
-                                                                 "Cortex-A12"),
-  ARM_CPU_OPT ("cortex-a15",   ARM_ARCH_V7VE,   FPU_ARCH_NEON_VFP_V4,
-                                                                 "Cortex-A15"),
-  ARM_CPU_OPT ("cortex-a17",   ARM_ARCH_V7VE,   FPU_ARCH_NEON_VFP_V4,
-                                                                 "Cortex-A17"),
-  ARM_CPU_OPT ("cortex-a32",    ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
-                                                                 "Cortex-A32"),
-  ARM_CPU_OPT ("cortex-a35",    ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
-                                                                 "Cortex-A35"),
-  ARM_CPU_OPT ("cortex-a53",    ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
-                                                                 "Cortex-A53"),
-  ARM_CPU_OPT ("cortex-a57",    ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
-                                                                 "Cortex-A57"),
-  ARM_CPU_OPT ("cortex-a72",    ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
-                                                                 "Cortex-A72"),
-  ARM_CPU_OPT ("cortex-a73",    ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
-                                                                 "Cortex-A73"),
-  ARM_CPU_OPT ("cortex-r4",    ARM_ARCH_V7R,    FPU_NONE,        "Cortex-R4"),
-  ARM_CPU_OPT ("cortex-r4f",   ARM_ARCH_V7R,    FPU_ARCH_VFP_V3D16,
-                                                                 "Cortex-R4F"),
-  ARM_CPU_OPT ("cortex-r5",    ARM_ARCH_V7R_IDIV,
-                                                FPU_NONE,        "Cortex-R5"),
-  ARM_CPU_OPT ("cortex-r7",    ARM_ARCH_V7R_IDIV,
-                                                FPU_ARCH_VFP_V3D16,
-                                                                 "Cortex-R7"),
-  ARM_CPU_OPT ("cortex-r8",    ARM_ARCH_V7R_IDIV,
-                                                FPU_ARCH_VFP_V3D16,
-                                                                 "Cortex-R8"),
-  ARM_CPU_OPT ("cortex-m33",   ARM_ARCH_V8M_MAIN_DSP,
-                                                FPU_NONE,        "Cortex-M33"),
-  ARM_CPU_OPT ("cortex-m23",   ARM_ARCH_V8M_BASE,
-                                                FPU_NONE,        "Cortex-M23"),
-  ARM_CPU_OPT ("cortex-m7",    ARM_ARCH_V7EM,   FPU_NONE,        "Cortex-M7"),
-  ARM_CPU_OPT ("cortex-m4",    ARM_ARCH_V7EM,   FPU_NONE,        "Cortex-M4"),
-  ARM_CPU_OPT ("cortex-m3",    ARM_ARCH_V7M,    FPU_NONE,        "Cortex-M3"),
-  ARM_CPU_OPT ("cortex-m1",    ARM_ARCH_V6SM,   FPU_NONE,        "Cortex-M1"),
-  ARM_CPU_OPT ("cortex-m0",    ARM_ARCH_V6SM,   FPU_NONE,        "Cortex-M0"),
-  ARM_CPU_OPT ("cortex-m0plus",        ARM_ARCH_V6SM,   FPU_NONE,        "Cortex-M0+"),
-  ARM_CPU_OPT ("exynos-m1",    ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
-                                                                 "Samsung " \
-                                                                 "Exynos M1"),
+  ARM_CPU_OPT ("arm9e-r0",       NULL,                ARM_ARCH_V5TExP,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm9e",                  NULL,                ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm926ej",       "ARM926EJ-S",        ARM_ARCH_V5TEJ,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm926ejs",      "ARM926EJ-S",        ARM_ARCH_V5TEJ,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm926ej-s",     NULL,                ARM_ARCH_V5TEJ,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm946e-r0",     NULL,                ARM_ARCH_V5TExP,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm946e",        "ARM946E-S",         ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm946e-s",      NULL,                ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm966e-r0",     NULL,                ARM_ARCH_V5TExP,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm966e",        "ARM966E-S",         ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm966e-s",      NULL,                ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm968e-s",      NULL,                ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm10t",         NULL,                ARM_ARCH_V5T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V1),
+  ARM_CPU_OPT ("arm10tdmi",      NULL,                ARM_ARCH_V5T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V1),
+  ARM_CPU_OPT ("arm10e",         NULL,                ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm1020",        "ARM1020E",          ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm1020t",       NULL,                ARM_ARCH_V5T,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V1),
+  ARM_CPU_OPT ("arm1020e",       NULL,                ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm1022e",       NULL,                ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm1026ejs",     "ARM1026EJ-S",       ARM_ARCH_V5TEJ,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm1026ej-s",    NULL,                ARM_ARCH_V5TEJ,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("fa606te",        NULL,                ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("fa616te",        NULL,                ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("fa626te",        NULL,                ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("fmp626",         NULL,                ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("fa726te",        NULL,                ARM_ARCH_V5TE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm1136js",      "ARM1136J-S",        ARM_ARCH_V6,
+              ARM_ARCH_NONE,
+              FPU_NONE),
+  ARM_CPU_OPT ("arm1136j-s",     NULL,                ARM_ARCH_V6,
+              ARM_ARCH_NONE,
+              FPU_NONE),
+  ARM_CPU_OPT ("arm1136jfs",     "ARM1136JF-S",       ARM_ARCH_V6,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm1136jf-s",    NULL,                ARM_ARCH_V6,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("mpcore",         "MPCore",            ARM_ARCH_V6K,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("mpcorenovfp",    "MPCore",            ARM_ARCH_V6K,
+              ARM_ARCH_NONE,
+              FPU_NONE),
+  ARM_CPU_OPT ("arm1156t2-s",    NULL,                ARM_ARCH_V6T2,
+              ARM_ARCH_NONE,
+              FPU_NONE),
+  ARM_CPU_OPT ("arm1156t2f-s",   NULL,                ARM_ARCH_V6T2,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("arm1176jz-s",    NULL,                ARM_ARCH_V6KZ,
+              ARM_ARCH_NONE,
+              FPU_NONE),
+  ARM_CPU_OPT ("arm1176jzf-s",   NULL,                ARM_ARCH_V6KZ,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("cortex-a5",      "Cortex-A5",         ARM_ARCH_V7A,
+              ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
+              FPU_NONE),
+  ARM_CPU_OPT ("cortex-a7",      "Cortex-A7",         ARM_ARCH_V7VE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_NEON_VFP_V4),
+  ARM_CPU_OPT ("cortex-a8",      "Cortex-A8",         ARM_ARCH_V7A,
+              ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
+              ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
+  ARM_CPU_OPT ("cortex-a9",      "Cortex-A9",         ARM_ARCH_V7A,
+              ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
+              ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
+  ARM_CPU_OPT ("cortex-a12",     "Cortex-A12",        ARM_ARCH_V7VE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_NEON_VFP_V4),
+  ARM_CPU_OPT ("cortex-a15",     "Cortex-A15",        ARM_ARCH_V7VE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_NEON_VFP_V4),
+  ARM_CPU_OPT ("cortex-a17",     "Cortex-A17",        ARM_ARCH_V7VE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_NEON_VFP_V4),
+  ARM_CPU_OPT ("cortex-a32",     "Cortex-A32",        ARM_ARCH_V8A,
+              ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
+              FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
+  ARM_CPU_OPT ("cortex-a35",     "Cortex-A35",        ARM_ARCH_V8A,
+              ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
+              FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
+  ARM_CPU_OPT ("cortex-a53",     "Cortex-A53",        ARM_ARCH_V8A,
+              ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
+              FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
+  ARM_CPU_OPT ("cortex-a57",     "Cortex-A57",        ARM_ARCH_V8A,
+              ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
+              FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
+  ARM_CPU_OPT ("cortex-a72",     "Cortex-A72",        ARM_ARCH_V8A,
+             ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
+             FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
+  ARM_CPU_OPT ("cortex-a73",     "Cortex-A73",        ARM_ARCH_V8A,
+             ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
+             FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
+  ARM_CPU_OPT ("cortex-r4",      "Cortex-R4",         ARM_ARCH_V7R,
+              ARM_ARCH_NONE,
+              FPU_NONE),
+  ARM_CPU_OPT ("cortex-r4f",     "Cortex-R4F",        ARM_ARCH_V7R,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V3D16),
+  ARM_CPU_OPT ("cortex-r5",      "Cortex-R5",         ARM_ARCH_V7R,
+              ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
+              FPU_NONE),
+  ARM_CPU_OPT ("cortex-r7",      "Cortex-R7",         ARM_ARCH_V7R,
+              ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
+              FPU_ARCH_VFP_V3D16),
+  ARM_CPU_OPT ("cortex-r8",      "Cortex-R8",         ARM_ARCH_V7R,
+              ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
+              FPU_ARCH_VFP_V3D16),
+  ARM_CPU_OPT ("cortex-m33",     "Cortex-M33",        ARM_ARCH_V8M_MAIN,
+              ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
+              FPU_NONE),
+  ARM_CPU_OPT ("cortex-m23",     "Cortex-M23",        ARM_ARCH_V8M_BASE,
+              ARM_ARCH_NONE,
+              FPU_NONE),
+  ARM_CPU_OPT ("cortex-m7",      "Cortex-M7",         ARM_ARCH_V7EM,
+              ARM_ARCH_NONE,
+              FPU_NONE),
+  ARM_CPU_OPT ("cortex-m4",      "Cortex-M4",         ARM_ARCH_V7EM,
+              ARM_ARCH_NONE,
+              FPU_NONE),
+  ARM_CPU_OPT ("cortex-m3",      "Cortex-M3",         ARM_ARCH_V7M,
+              ARM_ARCH_NONE,
+              FPU_NONE),
+  ARM_CPU_OPT ("cortex-m1",      "Cortex-M1",         ARM_ARCH_V6SM,
+              ARM_ARCH_NONE,
+              FPU_NONE),
+  ARM_CPU_OPT ("cortex-m0",      "Cortex-M0",         ARM_ARCH_V6SM,
+              ARM_ARCH_NONE,
+              FPU_NONE),
+  ARM_CPU_OPT ("cortex-m0plus",          "Cortex-M0+",        ARM_ARCH_V6SM,
+              ARM_ARCH_NONE,
+              FPU_NONE),
+  ARM_CPU_OPT ("exynos-m1",      "Samsung Exynos M1", ARM_ARCH_V8A,
+              ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
+              FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
 
   /* ??? XSCALE is really an architecture.  */
-  ARM_CPU_OPT ("xscale",       ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL),
+  ARM_CPU_OPT ("xscale",         NULL,                ARM_ARCH_XSCALE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+
   /* ??? iwmmxt is not a processor.  */
-  ARM_CPU_OPT ("iwmmxt",       ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("iwmmxt2",      ARM_ARCH_IWMMXT2,FPU_ARCH_VFP_V2, NULL),
-  ARM_CPU_OPT ("i80200",       ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL),
+  ARM_CPU_OPT ("iwmmxt",         NULL,                ARM_ARCH_IWMMXT,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("iwmmxt2",        NULL,                ARM_ARCH_IWMMXT2,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+  ARM_CPU_OPT ("i80200",         NULL,                ARM_ARCH_XSCALE,
+              ARM_ARCH_NONE,
+              FPU_ARCH_VFP_V2),
+
   /* Maverick */
-  ARM_CPU_OPT ("ep9312",       ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
-                                                FPU_ARCH_MAVERICK, "ARM920T"),
+  ARM_CPU_OPT ("ep9312",         "ARM920T",
+              ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
+              ARM_ARCH_NONE, FPU_ARCH_MAVERICK),
+
   /* Marvell processors.  */
-  ARM_CPU_OPT ("marvell-pj4",   ARM_FEATURE_CORE (ARM_AEXT_V7A | ARM_EXT_MP
-                                                 | ARM_EXT_SEC,
-                                                 ARM_EXT2_V6T2_V8M),
-                                               FPU_ARCH_VFP_V3D16, NULL),
-  ARM_CPU_OPT ("marvell-whitney", ARM_FEATURE_CORE (ARM_AEXT_V7A | ARM_EXT_MP
-                                                   | ARM_EXT_SEC,
-                                                   ARM_EXT2_V6T2_V8M),
-                                              FPU_ARCH_NEON_VFP_V4, NULL),
-  /* APM X-Gene family.  */
-  ARM_CPU_OPT ("xgene1",        ARM_ARCH_V8A,    FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
-                                                                 "APM X-Gene 1"),
-  ARM_CPU_OPT ("xgene2",        ARM_ARCH_V8A_CRC, FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
-                                                                 "APM X-Gene 2"),
+  ARM_CPU_OPT ("marvell-pj4",    NULL,                ARM_ARCH_V7A,
+              ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
+              FPU_ARCH_VFP_V3D16),
+  ARM_CPU_OPT ("marvell-whitney", NULL,                       ARM_ARCH_V7A,
+              ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
+              FPU_ARCH_NEON_VFP_V4),
 
-  { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
+  /* APM X-Gene family.  */
+  ARM_CPU_OPT ("xgene1",         "APM X-Gene 1",      ARM_ARCH_V8A,
+              ARM_ARCH_NONE,
+              FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
+  ARM_CPU_OPT ("xgene2",         "APM X-Gene 2",      ARM_ARCH_V8A,
+              ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
+              FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
+
+  { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
 };
 #undef ARM_CPU_OPT
 
@@ -26030,7 +26234,9 @@ arm_parse_cpu (const char *str)
   for (opt = arm_cpus; opt->name != NULL; opt++)
     if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
       {
-       mcpu_cpu_opt = &opt->value;
+       arm_feature_set *cpu_set = XNEW (arm_feature_set);
+       ARM_MERGE_FEATURE_SETS (*cpu_set, opt->value, opt->ext);
+       mcpu_cpu_opt = cpu_set;
        mcpu_fpu_opt = &opt->default_fpu;
        if (opt->canonical_name)
          {
@@ -26649,8 +26855,10 @@ s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
   for (opt = arm_cpus + 1; opt->name != NULL; opt++)
     if (streq (opt->name, name))
       {
-       mcpu_cpu_opt = &opt->value;
-       selected_cpu = opt->value;
+       arm_feature_set *cpu_set = XNEW (arm_feature_set);
+       ARM_MERGE_FEATURE_SETS (*cpu_set, opt->value, opt->ext);
+       mcpu_cpu_opt = cpu_set;
+       selected_cpu = *mcpu_cpu_opt;
        if (opt->canonical_name)
          strcpy (selected_cpu_name, opt->canonical_name);
        else