diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5df398c..cab5166 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2017-09-06  Richard Earnshaw  <rearnsha@arm.com>
+
+	* config.gcc (arm*-*-*): Don't add arm-isa.h to tm_p_file.
+	* config/arm/arm-isa.h: Delete.  Move definitions to ...
+	* arm-cpus.in: ... here.  Use new feature and fgroup values.
+	* config/arm/arm.c (arm_option_override): Use lower case for feature
+	bit names.
+	* config/arm/arm.h (TARGET_HARD_FLOAT): Likewise.
+	(TARGET_VFP3, TARGET_VFP5, TARGET_FMA): Likewise.
+	* config/arm/parsecpu.awk (END): Add new command 'isa'.
+	(isa_pfx): Delete.
+	(print_isa_bits_for): New function.
+	(gen_isa): New function.
+	(gen_comm_data): Use print_isa_bits_for.
+	(define feature): New keyword.
+	(define fgroup): New keyword.
+	* config/arm/t-arm (OPTIONS_H_EXTRA): Add arm-isa.h
+	(arm-isa.h): Add rule to generate file.
+	* common/config/arm/arm-common.c: (arm_canon_arch_option): Use lower
+	case for feature bit names.
+
 2017-09-06  Richard Biener  <rguenther@suse.de>
 
 	* tree-ssa-pre.c (NECESSARY): Remove.
diff --git a/gcc/common/config/arm/arm-common.c b/gcc/common/config/arm/arm-common.c
index 38bd3a7..7cb99ec 100644
--- a/gcc/common/config/arm/arm-common.c
+++ b/gcc/common/config/arm/arm-common.c
@@ -574,7 +574,7 @@ arm_canon_arch_option (int argc, const char **argv)
 	{
 	  /* The easiest and safest way to remove the default fpu
 	     capabilities is to look for a '+no..' option that removes
-	     the base FPU bit (isa_bit_VFPv2).  If that doesn't exist
+	     the base FPU bit (isa_bit_vfpv2).  If that doesn't exist
 	     then the best we can do is strip out all the bits that
 	     might be part of the most capable FPU we know about,
 	     which is "crypto-neon-fp-armv8".  */
@@ -586,7 +586,7 @@ arm_canon_arch_option (int argc, const char **argv)
 		   ++ext)
 		{
 		  if (ext->remove
-		      && check_isa_bits_for (ext->isa_bits, isa_bit_VFPv2))
+		      && check_isa_bits_for (ext->isa_bits, isa_bit_vfpv2))
 		    {
 		      arm_initialize_isa (fpu_isa, ext->isa_bits);
 		      bitmap_and_compl (target_isa, target_isa, fpu_isa);
@@ -620,7 +620,7 @@ arm_canon_arch_option (int argc, const char **argv)
     {
       /* Clearing the VFPv2 bit is sufficient to stop any extention that
 	 builds on the FPU from matching.  */
-      bitmap_clear_bit (target_isa, isa_bit_VFPv2);
+      bitmap_clear_bit (target_isa, isa_bit_vfpv2);
     }
 
   /* If we don't have a selected architecture by now, something's
@@ -692,8 +692,8 @@ arm_canon_arch_option (int argc, const char **argv)
      capable FPU variant that we do support.  This is sufficient for
      multilib selection.  */
 
-  if (bitmap_bit_p (target_isa_unsatisfied, isa_bit_VFPv2)
-      && bitmap_bit_p (fpu_isa, isa_bit_VFPv2))
+  if (bitmap_bit_p (target_isa_unsatisfied, isa_bit_vfpv2)
+      && bitmap_bit_p (fpu_isa, isa_bit_vfpv2))
     {
       std::list<candidate_extension *>::iterator ipoint = extensions.begin ();
 
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 428e99a..00fdcde 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -593,7 +593,7 @@ x86_64-*-*)
 	tm_file="vxworks-dummy.h ${tm_file}"
 	;;
 arm*-*-*)
-	tm_p_file="arm/arm-flags.h arm/arm-isa.h ${tm_p_file} arm/aarch-common-protos.h"
+	tm_p_file="arm/arm-flags.h ${tm_p_file} arm/aarch-common-protos.h"
 	tm_file="vxworks-dummy.h ${tm_file}"
 	;;
 mips*-*-* | sh*-*-* | sparc*-*-*)
diff --git a/gcc/config/arm/arm-cpus.in b/gcc/config/arm/arm-cpus.in
index d009a9e..07de4c9 100644
--- a/gcc/config/arm/arm-cpus.in
+++ b/gcc/config/arm/arm-cpus.in
@@ -40,6 +40,210 @@
 # names in the final compiler.  The order within each group is preserved and
 # forms the order for the list within the compiler.
 
+# Most objects in this file support forward references.  The major
+# exception is feature groups, which may only refer to previously
+# defined features or feature groups.  This is done to avoid the risk
+# of feature groups recursively referencing each other and causing
+# the parser to hang.
+
+# Features - general convention: all lower case.
+
+# Extended multiply
+define feature armv3m
+
+# 26-bit mode support
+define feature mode26
+
+# 32-bit mode support
+define feature mode32
+
+# Architecture rel 4
+define feature armv4
+
+# Architecture rel 5
+define feature armv5
+
+# Thumb aware.
+define feature thumb
+
+# Architecture rel 5e.
+define feature armv5e
+
+# XScale.
+define feature xscale
+
+# Architecture rel 6.
+define feature armv6
+
+# Architecture rel 6k.
+define feature armv6k
+
+# Thumb-2.
+define feature thumb2
+
+# Instructions not present in 'M' profile.
+define feature notm
+
+# Architecture uses be8 mode in big-endian.
+define feature be8
+
+# Thumb division instructions.
+define feature tdiv
+
+# Architecture rel 7e-m.
+define feature armv7em
+
+# Architecture rel 7.
+define feature armv7
+
+# ARM division instructions.
+define feature adiv
+
+# Architecture rel 8.
+define feature armv8
+
+# ARMv8 CRC32 instructions.
+define feature crc32
+
+# XScale v2 (Wireless MMX).
+define feature iwmmxt
+
+# XScale Wireless MMX2.
+define feature iwmmxt2
+
+# Architecture rel 8.1.
+define feature armv8_1
+
+# Architecutre rel 8.2.
+define feature armv8_2
+
+# M-Profile security extensions.
+define feature cmse
+
+# Floating point and Neon extensions.
+# VFPv1 is not supported in GCC.
+
+# Vector floating point v2.
+define feature vfpv2
+
+# Vector floating point v3.
+define feature vfpv3
+
+# Vector floating point v4.
+define feature vfpv4
+
+# Floating point v5.
+define feature fpv5
+
+# ARMv7-A LPAE.
+define feature lpae
+
+# Advanced SIMD instructions.
+define feature neon
+
+# Conversions to/from fp16 (VFPv3 extension).
+define feature fp16conv
+
+# Double precision operations supported.
+define feature fp_dbl
+
+# 32 Double precision registers.
+define feature fp_d32
+
+# Crypto extension to ARMv8.
+define feature crypto
+
+# FP16 data processing (half-precision float).
+define feature fp16
+
+
+# ISA Quirks (errata?).  Don't forget to add this to the fgroup
+# ALL_QUIRKS below.
+
+# No volatile memory in IT blocks.
+define feature quirk_no_volatile_ce
+
+# Previously mis-identified by GCC.
+define feature quirk_armv6kz
+
+# Cortex-M3 LDRD quirk.
+define feature quirk_cm3_ldrd
+
+# (Very) slow multiply operations.  Should probably be a tuning bit.
+define feature smallmul
+
+# Feature groups.  Conventionally all (or mostly) upper case.
+
+# List of all cryptographic extensions to stripout if crypto is
+# disabled.  Currently, that's trivial, but we define it anyway for
+# consistency with the SIMD and FP disable lists.
+define fgroup ALL_CRYPTO	crypto
+
+# List of all SIMD bits to strip out if SIMD is disabled.  This does
+# strip off 32 D-registers, but does not remove support for
+# double-precision FP.
+define fgroup ALL_SIMD	fp_d32 neon ALL_CRYPTO
+
+# List of all FPU bits to strip out if -mfpu is used to override the
+# default.  fp16 is deliberately missing from this list.
+define fgroup ALL_FPU_INTERNAL	vfpv2 vfpv3 vfpv4 fpv5 fp16conv fp_dbl ALL_SIMD
+
+# Similarly, but including fp16 and other extensions that aren't part of
+# -mfpu support.
+define fgroup ALL_FP	fp16 ALL_FPU_INTERNAL
+
+define fgroup ARMv2       notm
+define fgroup ARMv3       ARMv2 mode32
+define fgroup ARMv3m      ARMv3 armv3m
+define fgroup ARMv4       ARMv3m armv4
+define fgroup ARMv4t      ARMv4 thumb
+define fgroup ARMv5       ARMv4 armv5
+define fgroup ARMv5t      ARMv5 thumb
+define fgroup ARMv5e      ARMv5 armv5e
+define fgroup ARMv5te     ARMv5e thumb
+define fgroup ARMv5tej    ARMv5te
+define fgroup ARMv6       ARMv5te armv6 be8
+define fgroup ARMv6j      ARMv6
+define fgroup ARMv6k      ARMv6 armv6k
+define fgroup ARMv6z      ARMv6
+define fgroup ARMv6kz     ARMv6k quirk_armv6kz
+define fgroup ARMv6zk     ARMv6k
+define fgroup ARMv6t2     ARMv6 thumb2
+# This is suspect.  ARMv6-m doesn't really pull in any useful features
+# from ARMv5* or ARMv6.
+define fgroup ARMv6m      mode32 armv3m armv4 thumb armv5 armv5e armv6
+# This is suspect, the 'common' ARMv7 subset excludes the thumb2 'DSP' and
+# integer SIMD instructions that are in ARMv6T2.  */
+define fgroup ARMv7       ARMv6m thumb2 armv7
+
+define fgroup ARMv7a      ARMv7 notm armv6k
+define fgroup ARMv7ve     ARMv7a adiv tdiv lpae
+define fgroup ARMv7r      ARMv7a tdiv
+define fgroup ARMv7m      ARMv7 tdiv
+define fgroup ARMv7em     ARMv7m armv7em
+define fgroup ARMv8a      ARMv7ve armv8
+define fgroup ARMv8_1a    ARMv8a crc32 armv8_1
+define fgroup ARMv8_2a    ARMv8_1a armv8_2
+define fgroup ARMv8m_base ARMv6m armv8 cmse tdiv
+define fgroup ARMv8m_main ARMv7m armv8 cmse
+define fgroup ARMv8r      ARMv8a
+
+# Useful combinations.
+define fgroup VFPv2	vfpv2
+define fgroup VFPv3	VFPv2 vfpv3
+define fgroup VFPv4	VFPv3 vfpv4 fp16conv
+define fgroup FPv5	VFPv4 fpv5
+
+define fgroup FP_DBL	fp_dbl
+define fgroup FP_D32	FP_DBL fp_d32
+define fgroup FP_ARMv8	FPv5 FP_D32
+define fgroup NEON	FP_D32 neon
+define fgroup CRYPTO	NEON crypto
+
+# List of all quirk bits to strip out when comparing CPU features with
+# architectures.
+define fgroup ALL_QUIRKS   quirk_no_volatile_ce quirk_armv6kz quirk_cm3_ldrd
+
 # Architecture entries
 # format:
 # begin arch <name>
@@ -55,38 +259,38 @@ begin arch armv2
  tune for arm2
  tune flags CO_PROC NO_MODE32
  base 2
- isa ARMv2 bit_mode26
+ isa ARMv2 mode26
 end arch armv2
 
 begin arch armv2a
  tune for arm2
  tune flags CO_PROC NO_MODE32
  base 2
- isa ARMv2 bit_mode26
+ isa ARMv2 mode26
 end arch armv2a
 
 begin arch armv3
  tune for arm6
  tune flags CO_PROC
  base 3
- isa ARMv3 bit_mode26
+ isa ARMv3 mode26
 end arch armv3
 
 begin arch armv3m
  tune for arm7m
  tune flags CO_PROC
  base 3M
- isa ARMv3m bit_mode26
+ isa ARMv3m mode26
 end arch armv3m
 
 begin arch armv4
  tune for arm7tdmi
  tune flags CO_PROC
  base 4
- isa ARMv4 bit_mode26
+ isa ARMv4 mode26
 end arch armv4
 
-# Strictly, bit_mode26 is a permitted option for v4t, but there are no
+# Strictly, mode26 is a permitted option for v4t, but there are no
 # implementations that support it, so we will leave it out for now.
 begin arch armv4t
  tune for arm7tdmi
@@ -244,14 +448,14 @@ begin arch armv7-a
  option fp	       add VFPv3 FP_DBL
  optalias vfpv3-d16    fp
  option vfpv3	       add VFPv3 FP_D32
- option vfpv3-d16-fp16 add VFPv3 FP_DBL bit_fp16conv
- option vfpv3-fp16     add VFPv3 FP_DBL FP_D32 bit_fp16conv
+ option vfpv3-d16-fp16 add VFPv3 FP_DBL fp16conv
+ option vfpv3-fp16     add VFPv3 FP_DBL FP_D32 fp16conv
  option vfpv4-d16      add VFPv4 FP_DBL
  option vfpv4	       add VFPv4 FP_D32
  option simd	       add VFPv3 NEON
  optalias neon	       simd
  optalias neon-vfpv3   simd
- option neon-fp16      add VFPv3 NEON bit_fp16conv
+ option neon-fp16      add VFPv3 NEON fp16conv
  option neon-vfpv4     add VFPv4 NEON
  option nosimd	    remove ALL_SIMD
  option nofp	    remove ALL_FP
@@ -266,14 +470,14 @@ begin arch armv7ve
 # fp => VFPv4-d16, simd => neon-vfpv4
  option vfpv3-d16      add VFPv3 FP_DBL
  option vfpv3 	       add VFPv3 FP_D32
- option vfpv3-d16-fp16 add VFPv3 FP_DBL bit_fp16conv
- option vfpv3-fp16     add VFPv3 FP_DBL FP_D32 bit_fp16conv
+ option vfpv3-d16-fp16 add VFPv3 FP_DBL fp16conv
+ option vfpv3-fp16     add VFPv3 FP_DBL FP_D32 fp16conv
  option fp 	       add VFPv4 FP_DBL
  optalias vfpv4-d16    fp
  option vfpv4 	       add VFPv4 FP_D32
  option neon 	       add VFPv3 NEON
  optalias neon-vfpv3   neon
- option neon-fp16      add VFPv3 NEON bit_fp16conv
+ option neon-fp16      add VFPv3 NEON fp16conv
  option simd 	       add VFPv4 NEON
  optalias neon-vfpv4   simd
  option nosimd	    remove ALL_SIMD
@@ -291,9 +495,9 @@ begin arch armv7-r
  optalias vfpv3xd fp.sp
  option fp add VFPv3 FP_DBL
  optalias vfpv3-d16 fp
- option idiv add bit_adiv
+ option idiv add adiv
  option nofp remove ALL_FP
- option noidiv remove bit_adiv
+ option noidiv remove adiv
 end arch armv7-r
 
 begin arch armv7-m
@@ -327,7 +531,7 @@ begin arch armv8-a
  base 8A
  profile A
  isa ARMv8a
- option crc add bit_crc32
+ option crc add crc32
  option simd add FP_ARMv8 NEON
  option crypto add FP_ARMv8 CRYPTO
  option nocrypto remove ALL_CRYPTO
@@ -353,7 +557,7 @@ begin arch armv8.2-a
  profile A
  isa ARMv8_2a
  option simd add FP_ARMv8 NEON
- option fp16 add bit_fp16 FP_ARMv8 NEON
+ option fp16 add fp16 FP_ARMv8 NEON
  option crypto add FP_ARMv8 CRYPTO
  option nocrypto remove ALL_CRYPTO
  option nofp remove ALL_FP
@@ -372,12 +576,12 @@ begin arch armv8-m.main
  base 8M_MAIN
  profile M
  isa ARMv8m_main
- option dsp add bit_ARMv7em
+ option dsp add armv7em
 # fp => FPv5-sp-d16; fp.dp => FPv5-d16
  option fp add FPv5
  option fp.dp add FPv5 FP_DBL
  option nofp remove ALL_FP
- option nodsp remove bit_ARMv7em
+ option nodsp remove armv7em
 end arch armv8-m.main
 
 begin arch armv8-r
@@ -386,7 +590,7 @@ begin arch armv8-r
  base 8R
  profile R
  isa ARMv8r
- option crc add bit_crc32
+ option crc add crc32
 # fp.sp => fp-armv8 (d16); simd => simd + fp-armv8 + d32 + double precision
 # note: no fp option for fp-armv8 (d16) + double precision at the moment
  option fp.sp add FPv5
@@ -400,14 +604,14 @@ begin arch iwmmxt
  tune for iwmmxt
  tune flags LDSCHED STRONG XSCALE
  base 5TE
- isa ARMv5te bit_xscale bit_iwmmxt
+ isa ARMv5te xscale iwmmxt
 end arch iwmmxt
 
 begin arch iwmmxt2
  tune for iwmmxt2
  tune flags LDSCHED STRONG XSCALE
  base 5TE
- isa ARMv5te bit_xscale bit_iwmmxt bit_iwmmxt2
+ isa ARMv5te xscale iwmmxt iwmmxt2
 end arch iwmmxt2
 
 # CPU entries
@@ -783,7 +987,7 @@ end cpu arm1022e
 begin cpu xscale
  tune flags LDSCHED XSCALE
  architecture armv5te
- isa bit_xscale
+ isa xscale
  costs xscale
 end cpu xscale
 
@@ -961,14 +1165,14 @@ begin cpu generic-armv7-a
  fpu vfpv3-d16
  option vfpv3-d16 add VFPv3 FP_DBL
  option vfpv3 add VFPv3 FP_D32
- option vfpv3-d16-fp16 add VFPv3 FP_DBL bit_fp16conv
- option vfpv3-fp16 add VFPv3 FP_D32 bit_fp16conv
+ option vfpv3-d16-fp16 add VFPv3 FP_DBL fp16conv
+ option vfpv3-fp16 add VFPv3 FP_D32 fp16conv
  option vfpv4-d16 add VFPv4 FP_DBL
  option vfpv4 add VFPv4 FP_D32
  option simd add VFPv3 NEON
  optalias neon simd
  optalias neon-vfpv3 simd
- option neon-fp16 add VFPv3 NEON bit_fp16conv
+ option neon-fp16 add VFPv3 NEON fp16conv
  option neon-vfpv4 add VFPv4 NEON
  option nosimd remove ALL_SIMD
  option nofp remove ALL_FP
@@ -1344,7 +1548,7 @@ begin fpu vfpv3
 end fpu vfpv3
 
 begin fpu vfpv3-fp16
- isa VFPv3 FP_D32 bit_fp16conv
+ isa VFPv3 FP_D32 fp16conv
 end fpu vfpv3-fp16
 
 begin fpu vfpv3-d16
@@ -1352,7 +1556,7 @@ begin fpu vfpv3-d16
 end fpu vfpv3-d16
 
 begin fpu vfpv3-d16-fp16
- isa VFPv3 FP_DBL bit_fp16conv
+ isa VFPv3 FP_DBL fp16conv
 end fpu vfpv3-d16-fp16
 
 begin fpu vfpv3xd
@@ -1360,7 +1564,7 @@ begin fpu vfpv3xd
 end fpu vfpv3xd
 
 begin fpu vfpv3xd-fp16
- isa VFPv3 bit_fp16conv
+ isa VFPv3 fp16conv
 end fpu vfpv3xd-fp16
 
 begin fpu neon
@@ -1372,7 +1576,7 @@ begin fpu neon-vfpv3
 end fpu neon-vfpv3
 
 begin fpu neon-fp16
- isa VFPv3 NEON bit_fp16conv
+ isa VFPv3 NEON fp16conv
 end fpu neon-fp16
 
 begin fpu vfpv4
diff --git a/gcc/config/arm/arm-isa.h b/gcc/config/arm/arm-isa.h
deleted file mode 100644
index dbd29ea..0000000
--- a/gcc/config/arm/arm-isa.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/* ISA feature bits for ARM.
-   Copyright (C) 2016-2017 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.
-
-   Under Section 7 of GPL version 3, you are granted additional
-   permissions described in the GCC Runtime Library Exception, version
-   3.1, as published by the Free Software Foundation.
-
-   You should have received a copy of the GNU General Public License and
-   a copy of the GCC Runtime Library Exception along with this program;
-   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#ifndef ARM_ISA_FEATURE_H
-#define ARM_ISA_FEATURE_H
-
-enum isa_feature
-  {
-    isa_nobit,		/* Must be first.  */
-    isa_bit_ARMv3m,	/* Extended multiply.  */
-    isa_bit_mode26,	/* 26-bit mode support.  */
-    isa_bit_mode32,	/* 32-bit mode support.  */
-    isa_bit_ARMv4,	/* Architecture rel 4.  */
-    isa_bit_ARMv5,	/* Architecture rel 5.	*/
-    isa_bit_thumb,	/* Thumb aware.  */
-    isa_bit_ARMv5e,	/* Architecture rel 5e.  */
-    isa_bit_xscale,	/* XScale.  */
-    isa_bit_ARMv6,	/* Architecture rel 6.  */
-    isa_bit_ARMv6k,	/* Architecture rel 6k.  */
-    isa_bit_thumb2,	/* Thumb-2.  */
-    isa_bit_notm,	/* Instructions not present in 'M' profile.  */
-    isa_bit_be8,	/* Architecture uses be8 mode in big-endian.  */
-    isa_bit_tdiv,	/* Thumb division instructions.  */
-    isa_bit_ARMv7em,	/* Architecture rel 7e-m.  */
-    isa_bit_ARMv7,	/* Architecture rel 7.  */
-    isa_bit_adiv,	/* ARM division instructions.  */
-    isa_bit_ARMv8,	/* Architecture rel 8.  */
-    isa_bit_crc32,	/* ARMv8 CRC32 instructions.  */
-    isa_bit_iwmmxt,	/* XScale v2 (Wireless MMX).  */
-    isa_bit_iwmmxt2,	/* XScale Wireless MMX2.  */
-    isa_bit_ARMv8_1,	/* Architecture rel 8.1.  */
-    isa_bit_ARMv8_2,	/* Architecutre rel 8.2.  */
-    isa_bit_cmse,	/* M-Profile security extensions.  */
-    /* Floating point and Neon extensions.  */
-    /* VFPv1 is not supported in GCC.  */
-    isa_bit_VFPv2,	/* Vector floating point v2.  */
-    isa_bit_VFPv3,	/* Vector floating point v3.  */
-    isa_bit_VFPv4,	/* Vector floating point v4.  */
-    isa_bit_FPv5,	/* Floating point v5.  */
-    isa_bit_lpae,	/* ARMv7-A LPAE.  */
-    isa_bit_neon,	/* Advanced SIMD instructions.  */
-    isa_bit_fp16conv,	/* Conversions to/from fp16 (VFPv3 extension).  */
-    isa_bit_fp_dbl,	/* Double precision operations supported.  */
-    isa_bit_fp_d32,	/* 32 Double precision registers.  */
-    isa_bit_crypto,	/* Crypto extension to ARMv8.  */
-    isa_bit_fp16,	/* FP16 data processing (half-precision float).  */
-
-    /* ISA Quirks (errata?).  Don't forget to add this to the list of
-       all quirks below.  */
-    isa_quirk_no_volatile_ce,	/* No volatile memory in IT blocks.  */
-    isa_quirk_ARMv6kz,		/* Previously mis-identified by GCC.  */
-    isa_quirk_cm3_ldrd,		/* Cortex-M3 LDRD quirk.  */
-
-    /* Aren't currently, but probably should be tuning bits.  */
-    isa_bit_smallmul,	/* Slow multiply operations.  */
-
-    /* Tuning bits.  Should be elsewhere.  */
-    isa_tune_co_proc,	/* Has co-processor bus.  */
-    isa_tune_ldsched,	/* Load scheduling necessary.  */
-    isa_tune_strong,	/* StrongARM.  */
-    isa_tune_wbuf,	/* Schedule for write buffer ops (ARM6 & 7 only).  */
-
-    /* Must be last, used to dimension arrays.  */
-    isa_num_bits
-  };
-
-/* Helper macros for use when defining CPUs and architectures.
-
-   There must be no parenthesees in these lists, since they are used
-   to initialize arrays.  */
-
-#define ISA_ARMv2	isa_bit_notm
-#define ISA_ARMv3	ISA_ARMv2, isa_bit_mode32
-#define ISA_ARMv3m	ISA_ARMv3, isa_bit_ARMv3m
-#define ISA_ARMv4	ISA_ARMv3m, isa_bit_ARMv4
-#define ISA_ARMv4t	ISA_ARMv4, isa_bit_thumb
-#define ISA_ARMv5	ISA_ARMv4, isa_bit_ARMv5
-#define ISA_ARMv5t	ISA_ARMv5, isa_bit_thumb
-#define ISA_ARMv5e	ISA_ARMv5, isa_bit_ARMv5e
-#define ISA_ARMv5te	ISA_ARMv5e, isa_bit_thumb
-#define ISA_ARMv5tej	ISA_ARMv5te
-#define ISA_ARMv6	ISA_ARMv5te, isa_bit_ARMv6, isa_bit_be8
-#define ISA_ARMv6j	ISA_ARMv6
-#define ISA_ARMv6k	ISA_ARMv6, isa_bit_ARMv6k
-#define ISA_ARMv6z	ISA_ARMv6
-#define ISA_ARMv6kz	ISA_ARMv6k, isa_quirk_ARMv6kz
-#define ISA_ARMv6zk	ISA_ARMv6k
-#define ISA_ARMv6t2	ISA_ARMv6, isa_bit_thumb2
-
-/* This is suspect.  ARMv6-m doesn't really pull in any useful features
-   from ARMv5* or ARMv6.  */
-#define ISA_ARMv6m	isa_bit_mode32, isa_bit_ARMv3m, isa_bit_ARMv4, \
-    isa_bit_thumb, isa_bit_ARMv5, isa_bit_ARMv5e, isa_bit_ARMv6
-/* This is suspect, the 'common' ARMv7 subset excludes the thumb2 'DSP' and
-   integer SIMD instructions that are in ARMv6T2.  */
-#define ISA_ARMv7	ISA_ARMv6m, isa_bit_thumb2, isa_bit_ARMv7
-#define ISA_ARMv7a	ISA_ARMv7, isa_bit_notm, isa_bit_ARMv6k
-#define ISA_ARMv7ve	ISA_ARMv7a, isa_bit_adiv, isa_bit_tdiv, isa_bit_lpae
-#define ISA_ARMv7r	ISA_ARMv7a, isa_bit_tdiv
-#define ISA_ARMv7m	ISA_ARMv7, isa_bit_tdiv
-#define ISA_ARMv7em	ISA_ARMv7m, isa_bit_ARMv7em
-#define ISA_ARMv8a	ISA_ARMv7ve, isa_bit_ARMv8
-#define ISA_ARMv8_1a	ISA_ARMv8a, isa_bit_crc32, isa_bit_ARMv8_1
-#define ISA_ARMv8_2a	ISA_ARMv8_1a, isa_bit_ARMv8_2
-#define ISA_ARMv8m_base ISA_ARMv6m, isa_bit_ARMv8, isa_bit_cmse, isa_bit_tdiv
-#define ISA_ARMv8m_main ISA_ARMv7m, isa_bit_ARMv8, isa_bit_cmse
-#define ISA_ARMv8r	ISA_ARMv8a
-
-/* List of all cryptographic extensions to stripout if crypto is
-   disabled.  Currently, that's trivial, but we define it anyway for
-   consistency with the SIMD and FP disable lists.  */
-#define ISA_ALL_CRYPTO	isa_bit_crypto
-
-/* List of all SIMD bits to strip out if SIMD is disabled.  This does
-   strip off 32 D-registers, but does not remove support for
-   double-precision FP.  */
-#define ISA_ALL_SIMD	isa_bit_fp_d32, isa_bit_neon, ISA_ALL_CRYPTO
-
-/* List of all FPU bits to strip out if -mfpu is used to override the
-   default.  isa_bit_fp16 is deliberately missing from this list.  */
-#define ISA_ALL_FPU_INTERNAL						\
-  isa_bit_VFPv2, isa_bit_VFPv3, isa_bit_VFPv4, isa_bit_FPv5,		\
-  isa_bit_fp16conv, isa_bit_fp_dbl, ISA_ALL_SIMD
-
-/* Similarly, but including fp16 and other extensions that aren't part of
-   -mfpu support.  */
-#define ISA_ALL_FP	isa_bit_fp16, ISA_ALL_FPU_INTERNAL
-
-/* Useful combinations.  */
-#define ISA_VFPv2	isa_bit_VFPv2
-#define ISA_VFPv3	ISA_VFPv2, isa_bit_VFPv3
-#define ISA_VFPv4	ISA_VFPv3, isa_bit_VFPv4, isa_bit_fp16conv
-#define ISA_FPv5	ISA_VFPv4, isa_bit_FPv5
-
-#define ISA_FP_DBL	isa_bit_fp_dbl
-#define ISA_FP_D32	ISA_FP_DBL, isa_bit_fp_d32
-#define ISA_FP_ARMv8	ISA_FPv5, ISA_FP_D32
-#define ISA_NEON	ISA_FP_D32, isa_bit_neon
-#define ISA_CRYPTO	ISA_NEON, isa_bit_crypto
-
-/* List of all quirk bits to strip out when comparing CPU features with
-   architectures.  */
-#define ISA_ALL_QUIRKS	isa_quirk_no_volatile_ce, isa_quirk_ARMv6kz,	\
-    isa_quirk_cm3_ldrd
-
-/* Helper macro so that we can concatenate multiple features together
-   with arm-*.def files, since macro substitution can't have commas within an
-   argument that lacks parenthesis.  */
-#define ISA_FEAT(X)	X,
-#endif
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index f0e7788..bca8a34 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3361,22 +3361,22 @@ arm_option_override (void)
 
   /* Initialize boolean versions of the architectural flags, for use
      in the arm.md file.  */
-  arm_arch3m = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv3m);
-  arm_arch4 = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv4);
+  arm_arch3m = bitmap_bit_p (arm_active_target.isa, isa_bit_armv3m);
+  arm_arch4 = bitmap_bit_p (arm_active_target.isa, isa_bit_armv4);
   arm_arch4t = arm_arch4 && bitmap_bit_p (arm_active_target.isa, isa_bit_thumb);
-  arm_arch5 = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv5);
-  arm_arch5e = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv5e);
+  arm_arch5 = bitmap_bit_p (arm_active_target.isa, isa_bit_armv5);
+  arm_arch5e = bitmap_bit_p (arm_active_target.isa, isa_bit_armv5e);
   arm_arch5te = arm_arch5e
     && bitmap_bit_p (arm_active_target.isa, isa_bit_thumb);
-  arm_arch6 = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv6);
-  arm_arch6k = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv6k);
+  arm_arch6 = bitmap_bit_p (arm_active_target.isa, isa_bit_armv6);
+  arm_arch6k = bitmap_bit_p (arm_active_target.isa, isa_bit_armv6k);
   arm_arch_notm = bitmap_bit_p (arm_active_target.isa, isa_bit_notm);
   arm_arch6m = arm_arch6 && !arm_arch_notm;
-  arm_arch7 = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv7);
-  arm_arch7em = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv7em);
-  arm_arch8 = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv8);
-  arm_arch8_1 = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv8_1);
-  arm_arch8_2 = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv8_2);
+  arm_arch7 = bitmap_bit_p (arm_active_target.isa, isa_bit_armv7);
+  arm_arch7em = bitmap_bit_p (arm_active_target.isa, isa_bit_armv7em);
+  arm_arch8 = bitmap_bit_p (arm_active_target.isa, isa_bit_armv8);
+  arm_arch8_1 = bitmap_bit_p (arm_active_target.isa, isa_bit_armv8_1);
+  arm_arch8_2 = bitmap_bit_p (arm_active_target.isa, isa_bit_armv8_2);
   arm_arch_thumb1 = bitmap_bit_p (arm_active_target.isa, isa_bit_thumb);
   arm_arch_thumb2 = bitmap_bit_p (arm_active_target.isa, isa_bit_thumb2);
   arm_arch_xscale = bitmap_bit_p (arm_active_target.isa, isa_bit_xscale);
@@ -3406,9 +3406,9 @@ arm_option_override (void)
 
   /* And finally, set up some quirks.  */
   arm_arch_no_volatile_ce
-    = bitmap_bit_p (arm_active_target.isa, isa_quirk_no_volatile_ce);
-  arm_arch6kz
-    = arm_arch6k && bitmap_bit_p (arm_active_target.isa, isa_quirk_ARMv6kz);
+    = bitmap_bit_p (arm_active_target.isa, isa_bit_quirk_no_volatile_ce);
+  arm_arch6kz = arm_arch6k && bitmap_bit_p (arm_active_target.isa,
+					    isa_bit_quirk_armv6kz);
 
   /* V5 code we generate is completely interworking capable, so we turn off
      TARGET_INTERWORK here to avoid many tests later on.  */
@@ -3453,7 +3453,7 @@ arm_option_override (void)
       else if (TARGET_HARD_FLOAT_ABI)
 	{
 	  arm_pcs_default = ARM_PCS_AAPCS_VFP;
-	  if (!bitmap_bit_p (arm_active_target.isa, isa_bit_VFPv2))
+	  if (!bitmap_bit_p (arm_active_target.isa, isa_bit_vfpv2))
 	    error ("-mfloat-abi=hard: selected processor lacks an FPU");
 	}
       else
@@ -3556,7 +3556,7 @@ arm_option_override (void)
   /* Enable -mfix-cortex-m3-ldrd by default for Cortex-M3 cores.  */
   if (fix_cm3_ldrd == 2)
     {
-      if (bitmap_bit_p (arm_active_target.isa, isa_quirk_cm3_ldrd))
+      if (bitmap_bit_p (arm_active_target.isa, isa_bit_quirk_cm3_ldrd))
 	fix_cm3_ldrd = 1;
       else
 	fix_cm3_ldrd = 0;
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 5fdb65b..2d71e8f 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -122,7 +122,7 @@ extern tree arm_fp16_type_node;
 /* Use hardware floating point instructions. */
 #define TARGET_HARD_FLOAT	(arm_float_abi != ARM_FLOAT_ABI_SOFT	\
 				 && bitmap_bit_p (arm_active_target.isa, \
-						  isa_bit_VFPv2))
+						  isa_bit_vfpv2))
 #define TARGET_SOFT_FLOAT	(!TARGET_HARD_FLOAT)
 /* User has permitted use of FP instructions, if they exist for this
    target.  */
@@ -169,10 +169,10 @@ extern tree arm_fp16_type_node;
 #define TARGET_VFPD32 (bitmap_bit_p (arm_active_target.isa, isa_bit_fp_d32))
 
 /* FPU supports VFPv3 instructions.  */
-#define TARGET_VFP3 (bitmap_bit_p (arm_active_target.isa, isa_bit_VFPv3))
+#define TARGET_VFP3 (bitmap_bit_p (arm_active_target.isa, isa_bit_vfpv3))
 
 /* FPU supports FPv5 instructions.  */
-#define TARGET_VFP5 (bitmap_bit_p (arm_active_target.isa, isa_bit_FPv5))
+#define TARGET_VFP5 (bitmap_bit_p (arm_active_target.isa, isa_bit_fpv5))
 
 /* FPU only supports VFP single-precision instructions.  */
 #define TARGET_VFP_SINGLE (!TARGET_VFP_DOUBLE)
@@ -194,7 +194,7 @@ extern tree arm_fp16_type_node;
   (TARGET_HARD_FLOAT && (TARGET_FP16 && TARGET_VFP5))
 
 /* FPU supports fused-multiply-add operations.  */
-#define TARGET_FMA (bitmap_bit_p (arm_active_target.isa, isa_bit_VFPv4))
+#define TARGET_FMA (bitmap_bit_p (arm_active_target.isa, isa_bit_vfpv4))
 
 /* FPU supports Crypto extensions.  */
 #define TARGET_CRYPTO (bitmap_bit_p (arm_active_target.isa, isa_bit_crypto))
diff --git a/gcc/config/arm/parsecpu.awk b/gcc/config/arm/parsecpu.awk
index 070d193..d07d3fc 100644
--- a/gcc/config/arm/parsecpu.awk
+++ b/gcc/config/arm/parsecpu.awk
@@ -22,6 +22,7 @@
 #	data: Print the standard 'C' data tables for the CPUs
 #	common-data: Print the 'C' data for shared driver/compiler files
 #	headers: Print the standard 'C' headers for the CPUs
+#	isa: Generate the arm-isa.h header
 #	md: Print the machine description fragment
 #	opt: Print the option tables fragment
 #	chkcpu <name>: Checks that <name> is a valid CPU
@@ -83,9 +84,44 @@ function tune_flag_pfx (f) {
     return "TF_" f
 }
 
-function isa_pfx (f) {
-    if (f ~ /^(bit|quirk)_.*/) return "isa_" f
-    return "ISA_" f
+# Print out the bits for the features in FLIST, which may be a
+# mixture of fgroup and individual bits.  Print each feature needed
+# exactly once.  Terminate the list with isa_nobit.  Prefix each line by
+# INDENT.  Does not print a new line at the end.
+function print_isa_bits_for (flist, indent) {
+    nbits = split (flist, bits)
+
+    for (bit = 1; bit <= nbits; bit++) {
+	if (bits[bit] in features) {
+	    pbit[bits[bit]] = 1
+	} else if (bits[bit] in fgroup) {
+	    for (gbits in fgrp_bits) {
+		split (gbits, bitsep, SUBSEP)
+		if (bitsep[1] == bits[bit]) {
+		    pbit[bitsep[2]] = 1
+		}
+	    }
+	} else fatal("feature " bits[bit] " not declared")
+    }
+    zbit = ORS
+    ORS = ""
+    print indent "{\n" indent "  "
+    ORS = ", "
+    count = 0
+    for (bname in pbit) {
+	print "isa_bit_" bname
+	count++
+	if (count == 4) {
+	    count = 0
+	    ORS = ""
+	    print "\n" indent "  "
+	    ORS = ", "
+	}
+    }
+    ORS = ""
+    print "isa_nobit\n" indent "}"
+    ORS = zbit
+    delete pbit
 }
 
 function gen_headers () {
@@ -125,6 +161,35 @@ function gen_headers () {
     print "};"
 }
 
+function gen_isa () {
+    boilerplate("C")
+    print "enum isa_feature {"
+    print "  isa_nobit = 0,"
+    for (fbit in features) {
+	print "  isa_bit_" fbit ","
+    }
+    print "  isa_num_bits"
+    print "};\n"
+
+    for (fgrp in fgroup) {
+	print "#define ISA_"fgrp " \\"
+	z = ORS
+	ORS = ""
+	first = 1
+	for (bitcomb in fgrp_bits) {
+	    split (bitcomb, bitsep, SUBSEP)
+	    if (bitsep[1] == fgrp) {
+		if (first) {
+		    first = 0
+		} else print ", \\\n"
+		print "  isa_bit_" bitsep[2]
+	    }
+	}
+	ORS = z
+	print "\n"
+    }
+}
+
 function gen_data () {
     boilerplate("C")
 
@@ -155,7 +220,6 @@ function gen_data () {
     }
     print "  {TARGET_CPU_arm_none, 0, NULL}"
     print "};"
-    
 }
 
 function gen_comm_data () {
@@ -172,8 +236,8 @@ function gen_comm_data () {
 		print "  {"
 		print "    \"" opts[opt] "\", " \
 		    cpu_opt_remove[cpus[n],opts[opt]] ", false,"
-		print "    { " cpu_opt_isa[cpus[n],opts[opt]] ", isa_nobit }"
-		print "  },"
+		print_isa_bits_for(cpu_opt_isa[cpus[n],opts[opt]], "    ")
+		print "\n  },"
 	    }
 	    if (cpus[n] in cpu_optaliases) {
 		naliases = split (cpu_optaliases[cpus[n]], aliases)
@@ -188,8 +252,8 @@ function gen_comm_data () {
 		    print "  {"
 		    print "    \"" aliases[alias] "\", " \
 			cpu_opt_remove[cpus[n],equiv] ", true, "
-		    print "    { " cpu_opt_isa[cpus[n],equiv] ", isa_nobit }"
-		    print "  },"
+		    print_isa_bits_for(cpu_opt_isa[cpus[n],equiv], "    ")
+		    print "\n  },"
 		}
 	    }
 	    print "  { NULL, false, false, {isa_nobit}}"
@@ -214,8 +278,7 @@ function gen_comm_data () {
 	if (! (feats[1] in arch_isa)) {
 	    fatal("unknown arch " feats[1] " for cpu " cpus[n])
 	}
-	print "      {"
-	print "        " arch_isa[feats[1]] ","
+	all_isa_bits = 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])
@@ -223,42 +286,16 @@ function gen_comm_data () {
 	    if (arch_opt_remove[feats[1],feats[m]] == "true") {
 		fatal("cannot remove features from architecture specs")
 	    }
-	    # The isa_features array that is being initialized here has a length
-	    # of max isa_bit_num, which is the last entry in the enum.
-	    # Logically this means that the number of features is implicitly
-	    # never more than the number of feature bits we have.  This is only
-	    # true if we don't emit duplicates here.  So keep track of which
-	    # options we have already emitted so we don't emit them twice.
-	    nopts = split (arch_opt_isa[feats[1],feats[m]], opts, ",")
-	    for (i = 1; i <= nopts; i++) {
-		if (! (opts[i] in seen)) {
-		  print "        " opts[i] ","
-		  seen[opts[i]]
-		}
-	    }
+	    all_isa_bits = all_isa_bits " " arch_opt_isa[feats[1],feats[m]]
 	}
 	if (cpus[n] in cpu_fpu) {
-	    nopts = split (fpu_isa[cpu_fpu[cpus[n]]], opts, ",")
-	    for (i = 1; i <= nopts; i++) {
-		if (! (opts[i] in seen)) {
-		  print "        " opts[i] ","
-		  seen[opts[i]]
-		}
-	    }
+	    all_isa_bits = all_isa_bits " " fpu_isa[cpu_fpu[cpus[n]]]
 	}
 	if (cpus[n] in cpu_isa) {
-	    nopts = split (cpu_isa[cpus[n]], opts, ",")
-	    for (i = 1; i <= nopts; i++) {
-		if (! (opts[i] in seen)) {
-		  print "        " opts[i] ","
-		  seen[opts[i]]
-		}
-	    }
+	    all_isa_bits = all_isa_bits " " cpu_isa[cpus[n]]
 	}
-	delete seen
-	print "        isa_nobit"
-	print "      }"
-	print "    },"
+	print_isa_bits_for(all_isa_bits, "      ")
+	print "\n    },"
 	# arch
 	print "    TARGET_ARCH_" arch_cnames[feats[1]]
 	print "  },"
@@ -278,8 +315,8 @@ function gen_comm_data () {
 		print "  {"
 		print "    \"" opts[opt] "\", " \
 		    arch_opt_remove[archs[n],opts[opt]] ", false,"
-		print "    { " arch_opt_isa[archs[n],opts[opt]] ", isa_nobit }"
-		print "  },"
+		print_isa_bits_for(arch_opt_isa[archs[n],opts[opt]], "    ")
+		print "\n  },"
 	    }
 	    if (archs[n] in arch_optaliases) {
 		naliases = split (arch_optaliases[archs[n]], aliases)
@@ -294,8 +331,8 @@ function gen_comm_data () {
 		    print "  {"
 		    print "    \"" aliases[alias] "\", " \
 			arch_opt_remove[archs[n],equiv] ", true, "
-		    print "    { " arch_opt_isa[archs[n],equiv] ", isa_nobit }"
-		    print "  },"
+		    print_isa_bits_for(arch_opt_isa[archs[n],equiv], "    ")
+		    print "\n  },"
 		}
 	    }
 	    print "  { NULL, false, false, {isa_nobit}}"
@@ -321,10 +358,8 @@ function gen_comm_data () {
 	    print "    arch_opttab_" arch_cnames[archs[n]] ","
 	} else print "    NULL,"
 	# common.isa_bits
-	print "    {"
-	print "      " arch_isa[archs[n]] ","
-	print "      isa_nobit"
-	print "    },"
+	print_isa_bits_for(arch_isa[archs[n]], "    ")
+	print ","
 	# arch, base_arch
 	print "    \"" arch_base[archs[n]] "\", BASE_ARCH_" \
 	    arch_base[archs[n]] ","
@@ -351,11 +386,8 @@ function gen_comm_data () {
     for (n = 1; n <= nfpus; n++) {
 	print "  {"
 	print "    \"" fpus[n] "\","
-	print "    {"
-	print "      " fpu_isa[fpus[n]] ","
-	print "      isa_nobit"
-	print "    }"
-	print "  },"
+	print_isa_bits_for(fpu_isa[fpus[n]], "    ")
+	print "\n  },"
     }
 
     print "};"
@@ -482,6 +514,43 @@ BEGIN {
     parse_ok = 1
 }
 
+/^define feature / {
+    if (NF != 3) fatal("syntax: define feature <name>")
+    toplevel()
+    fbit = $3
+    if (fbit in features) fatal("feature " fbit " already defined")
+    features[fbit] = 1
+    parse_ok = 1
+}
+
+/^define fgroup / {
+    if (NF < 4) fatal("syntax: define fgroup <name> <feature> [<feature>]*")
+    toplevel()
+    fgrp = $3
+    if (fgrp in fgroup) fatal("feature group " fgrp " already defined")
+    if (fgrp in features) fatal("feature group " fgrp " aliases a feature")
+    fcount = NF
+    for (n = 4; n <= fcount; n++) {
+	feat = $n
+	if (feat in features) {
+	    fgrp_bits[fgrp,feat] = 1
+	} else if (feat in fgroup) {
+	    # fgroups may reference other fgroups, copy their bits
+	    # to our bits.  To avoid recursion we don't set fgroup[fgrp]
+	    # until after we have done this, so such attempts will result
+	    # in an invalid group definition.
+	    for (bitcomb in fgrp_bits) {
+		split (bitcomb, bitsep, SUBSEP)
+		if (bitsep[1] == feat) {
+		    fgrp_bits[fgrp,bitsep[2]] = 1
+		}
+	    }
+	} else fatal("feature group member " feat " unrecognized")
+    }
+    fgroup[fgrp] = 1
+    parse_ok = 1
+}
+
 /^begin fpu / {
     toplevel()
     fpu_name = $3
@@ -587,8 +656,8 @@ BEGIN {
     flag_count = NF
     for (n = 2; n <= flag_count; n++) {
 	if (n == 2) {
-	    flags = isa_pfx($n)
-	} else flags = flags "," isa_pfx($n)
+	    flags = $n
+	} else flags = flags " " $n
     }
     if (cpu_name != "") {
 	cpu_isa[cpu_name] = flags
@@ -611,8 +680,8 @@ BEGIN {
     flag_count = NF
     for (n = 4; n <= flag_count; n++) {
 	if (n == 4) {
-	    flags = isa_pfx($n)
-	} else flags = flags "," isa_pfx($n)
+	    flags = $n
+	} else flags = flags " " $n
     }
     if (cpu_name != "") {
 	cpu_opts[cpu_name] = cpu_opts[cpu_name] " " name
@@ -669,6 +738,8 @@ END {
 	gen_comm_data()
     } else if (cmd == "headers") {
 	gen_headers()
+    } else if (cmd == "isa") {
+	gen_isa()
     } else if (cmd == "md") {
 	gen_md()
     } else if (cmd == "opt") {
diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm
index 16177e0..2cd472a 100644
--- a/gcc/config/arm/t-arm
+++ b/gcc/config/arm/t-arm
@@ -20,6 +20,7 @@
 
 TM_H += arm-cpu.h
 GTM_H += arm-cpu.h
+OPTIONS_H_EXTRA += arm-isa.h
 
 # All md files - except for arm.md.
 # This list should be kept in alphabetical order and updated whenever an md
@@ -87,6 +88,14 @@ s-arm-cpu: $(srcdir)/config/arm/parsecpu.awk \
 	$(SHELL) $(srcdir)/../move-if-change tmp-arm-cpu.h arm-cpu.h
 	$(STAMP) s-arm-cpu
 
+arm-isa.h: s-arm-isa ; @true
+s-arm-isa: $(srcdir)/config/arm/parsecpu.awk \
+  $(srcdir)/config/arm/arm-cpus.in
+	$(AWK) -f $(srcdir)/config/arm/parsecpu.awk -v cmd=isa \
+		$(srcdir)/config/arm/arm-cpus.in > tmp-arm-isa.h
+	$(SHELL) $(srcdir)/../move-if-change tmp-arm-isa.h arm-isa.h
+	$(STAMP) s-arm-isa
+
 arm-cpu-data.h: s-arm-data ; @true
 s-arm-data: $(srcdir)/config/arm/parsecpu.awk \
   $(srcdir)/config/arm/arm-cpus.in

