mbox series

[00/30,ARM] Reworking the -mcpu, -march and -mfpu options

Message ID cover.1497004220.git.Richard.Earnshaw@arm.com
Headers show
Series Reworking the -mcpu, -march and -mfpu options | expand

Message

Richard Earnshaw (lists) June 9, 2017, 12:53 p.m. UTC
During the ARM BoF at the Cauldron last year I mentioned that I wanted
to rework the way GCC on ARM handles the command line options.  The
problem was that most users, and even many experts, can't remember
which FPU/SIMD unit comes with which CPU and that consequently many
users were inadvertenly generating sub-optimal code for their system.

This patch series implements the proposed change and provides support
for a generic way of adding optional features to architectures and CPU
names.  The documentation patches at the end of the series explain the
new syntax, so I won't repeat all that here.  Suffice to say here that
the result is that the -mfpu option now defaults to 'auto', which
allows the compiler to infer the floating-point and simd options from
the CPU/architecture options and that these options can normally be
expressed in a context-specific manner like +simd or +fp without
having to know precisely which variant is implemented.  Long term I'd
like to deprecate -mfpu and entirely move over to the new syntax; but
it's too early to start that process now.

All the patches in the series should build a working basic compiler,
but the multilib selection will not work correctly until the relevant
patches towards the end are applied.  It is not really feasible to
retain that functionality without collapsing too many of the patches
together into one hunk.  It's also possible that some tests in the
testsuite may exhibit transient misbehaviour, but there should be no
regressions by the end of the sequence (some tests no-longer run in
the default configurations because the default CPU does not have
floating-point support).

Just two patches are to the generic code, but both are fairly trivial.
One permits the sbitmap code to be used in the driver programs and the
other provides a way of escaping the meta-character in some multilib
reuse strings.

I won't apply any of this series until those two patches have been
approved, and I won't commit anything before the middle of next week
even then.  This is a fairly complex change and it deserves some time
for people to comment before committing.

R.

Richard Earnshaw (30):
  [arm] Use strings for -march, -mcpu and -mtune options
  [arm] Rewrite -march and -mcpu options for passing to the assembler
  [arm] Don't pass -mfpu=auto through to the assembler.
  [arm] Allow +opt on arbitrary cpu and architecture specifications
  [arm] Add architectural options
  [arm] Add default FPUs for CPUs.
  [build] Make sbitmap code available to the driver programs
  [arm] Split CPU, architecture and tuning data tables.
  [ARM] Move cpu and architecture option name parsing code to
    arm-common.c
  [arm] Use standard option parsing code for detecting thumb-only
    targets
  [arm] Allow CPU and architecture extensions to be defined as aliases
  [arm] Allow new extended syntax CPU and architecture names during
    configure
  [arm] Force a CPU default in the config args defaults list.
  [arm] Generate a canonical form for -march
  [arm] Make -mfloat-abi=softfp work when there are no FPU instructions
  [arm] Update basic multilib configuration
  [arm] Make 'auto' the default FPU selection option.
  [arm] Rewrite t-aprofile using new selector methodology
  [arm] Explicitly set .fpu in cmse_nonsecure_call.S
  [genmultilib] Allow explicit periods to be escaped in MULTILIB_REUSE
  [arm][testsuite] Use -march=armv7-a+fp when testing hard-float ABI.
  [arm] Rewrite t-rmprofile multilib specification
  [arm][rtems] Update t-rtems for new option framework
  [arm][linux-eabi] Ensure all multilib variables are reset
  [arm][phoenix] reset all multilib variables
  [arm] Rework multlib builds for symbianelf
  [arm][fuchsia] Rework multilib support
  [arm] Add a few missing architecture extension options.
  [arm][doc] Document new -march= syntax.
  [arm][doc] Document changes to -mcpu, -mtune and -mfpu.

 gcc/Makefile.in                           |    2 +-
 gcc/common/config/arm/arm-common.c        |  651 +++++++-
 gcc/config.gcc                            |   17 +-
 gcc/config/arm/arm-builtins.c             |    4 +-
 gcc/config/arm/arm-cpu-cdata.h            | 2444 +++++++++++++++++++++++------
 gcc/config/arm/arm-cpu-data.h             | 1410 ++---------------
 gcc/config/arm/arm-cpu.h                  |   38 +
 gcc/config/arm/arm-cpus.in                |  237 ++-
 gcc/config/arm/arm-isa.h                  |   20 +-
 gcc/config/arm/arm-protos.h               |   56 +-
 gcc/config/arm/arm-tables.opt             |   21 +-
 gcc/config/arm/arm.c                      |  337 ++--
 gcc/config/arm/arm.h                      |   75 +-
 gcc/config/arm/arm.opt                    |   15 +-
 gcc/config/arm/bpabi.h                    |    4 -
 gcc/config/arm/elf.h                      |    6 +-
 gcc/config/arm/linux-elf.h                |    3 -
 gcc/config/arm/netbsd-elf.h               |    4 -
 gcc/config/arm/parsecpu.awk               |  295 +++-
 gcc/config/arm/t-aprofile                 |  200 +--
 gcc/config/arm/t-arm-elf                  |  173 +-
 gcc/config/arm/t-fuchsia                  |   33 +
 gcc/config/arm/t-linux-eabi               |    4 +
 gcc/config/arm/t-multilib                 |  126 +-
 gcc/config/arm/t-phoenix                  |   20 +-
 gcc/config/arm/t-rmprofile                |  147 +-
 gcc/config/arm/t-rtems                    |   49 +-
 gcc/config/arm/t-symbian                  |   34 +-
 gcc/config/arm/vxworks.h                  |    2 -
 gcc/doc/fragments.texi                    |   10 +-
 gcc/doc/invoke.texi                       |  371 ++++-
 gcc/genmultilib                           |    4 +-
 gcc/testsuite/gcc.dg/pr59418.c            |    2 +-
 gcc/testsuite/gcc.target/arm/multilib.exp |  685 ++++++++
 gcc/testsuite/gcc.target/arm/pr51915.c    |    2 +-
 gcc/testsuite/gcc.target/arm/pr52006.c    |    2 +-
 gcc/testsuite/gcc.target/arm/pr53187.c    |    2 +-
 libgcc/config/arm/cmse_nonsecure_call.S   |    8 +
 38 files changed, 5073 insertions(+), 2440 deletions(-)
 create mode 100644 gcc/config/arm/t-fuchsia
 create mode 100644 gcc/testsuite/gcc.target/arm/multilib.exp

----------------2.7.4--

Comments

Christophe Lyon June 9, 2017, 10:45 p.m. UTC | #1
Hi Richard,


On 9 June 2017 at 14:53, Richard Earnshaw <Richard.Earnshaw@arm.com> wrote:
>

> During the ARM BoF at the Cauldron last year I mentioned that I wanted

> to rework the way GCC on ARM handles the command line options.  The

> problem was that most users, and even many experts, can't remember

> which FPU/SIMD unit comes with which CPU and that consequently many

> users were inadvertenly generating sub-optimal code for their system.

>

> This patch series implements the proposed change and provides support

> for a generic way of adding optional features to architectures and CPU

> names.  The documentation patches at the end of the series explain the

> new syntax, so I won't repeat all that here.  Suffice to say here that

> the result is that the -mfpu option now defaults to 'auto', which

> allows the compiler to infer the floating-point and simd options from

> the CPU/architecture options and that these options can normally be

> expressed in a context-specific manner like +simd or +fp without

> having to know precisely which variant is implemented.  Long term I'd

> like to deprecate -mfpu and entirely move over to the new syntax; but

> it's too early to start that process now.

>

> All the patches in the series should build a working basic compiler,

> but the multilib selection will not work correctly until the relevant

> patches towards the end are applied.  It is not really feasible to

> retain that functionality without collapsing too many of the patches

> together into one hunk.  It's also possible that some tests in the

> testsuite may exhibit transient misbehaviour, but there should be no

> regressions by the end of the sequence (some tests no-longer run in

> the default configurations because the default CPU does not have

> floating-point support).

>

> Just two patches are to the generic code, but both are fairly trivial.

> One permits the sbitmap code to be used in the driver programs and the

> other provides a way of escaping the meta-character in some multilib

> reuse strings.

>

> I won't apply any of this series until those two patches have been

> approved, and I won't commit anything before the middle of next week

> even then.  This is a fairly complex change and it deserves some time

> for people to comment before committing.

>

> R.

>

> Richard Earnshaw (30):

>   [arm] Use strings for -march, -mcpu and -mtune options

>   [arm] Rewrite -march and -mcpu options for passing to the assembler

>   [arm] Don't pass -mfpu=auto through to the assembler.

>   [arm] Allow +opt on arbitrary cpu and architecture specifications

>   [arm] Add architectural options

>   [arm] Add default FPUs for CPUs.

>   [build] Make sbitmap code available to the driver programs

>   [arm] Split CPU, architecture and tuning data tables.

>   [ARM] Move cpu and architecture option name parsing code to

>     arm-common.c

>   [arm] Use standard option parsing code for detecting thumb-only

>     targets

>   [arm] Allow CPU and architecture extensions to be defined as aliases

>   [arm] Allow new extended syntax CPU and architecture names during

>     configure

>   [arm] Force a CPU default in the config args defaults list.

>   [arm] Generate a canonical form for -march

>   [arm] Make -mfloat-abi=softfp work when there are no FPU instructions

>   [arm] Update basic multilib configuration

>   [arm] Make 'auto' the default FPU selection option.

>   [arm] Rewrite t-aprofile using new selector methodology

>   [arm] Explicitly set .fpu in cmse_nonsecure_call.S

>   [genmultilib] Allow explicit periods to be escaped in MULTILIB_REUSE

>   [arm][testsuite] Use -march=armv7-a+fp when testing hard-float ABI.

>   [arm] Rewrite t-rmprofile multilib specification

>   [arm][rtems] Update t-rtems for new option framework

>   [arm][linux-eabi] Ensure all multilib variables are reset

>   [arm][phoenix] reset all multilib variables

>   [arm] Rework multlib builds for symbianelf

>   [arm][fuchsia] Rework multilib support

>   [arm] Add a few missing architecture extension options.

>   [arm][doc] Document new -march= syntax.

>   [arm][doc] Document changes to -mcpu, -mtune and -mfpu.

>

>  gcc/Makefile.in                           |    2 +-

>  gcc/common/config/arm/arm-common.c        |  651 +++++++-

>  gcc/config.gcc                            |   17 +-

>  gcc/config/arm/arm-builtins.c             |    4 +-

>  gcc/config/arm/arm-cpu-cdata.h            | 2444 +++++++++++++++++++++++------

>  gcc/config/arm/arm-cpu-data.h             | 1410 ++---------------

>  gcc/config/arm/arm-cpu.h                  |   38 +

>  gcc/config/arm/arm-cpus.in                |  237 ++-

>  gcc/config/arm/arm-isa.h                  |   20 +-

>  gcc/config/arm/arm-protos.h               |   56 +-

>  gcc/config/arm/arm-tables.opt             |   21 +-

>  gcc/config/arm/arm.c                      |  337 ++--

>  gcc/config/arm/arm.h                      |   75 +-

>  gcc/config/arm/arm.opt                    |   15 +-

>  gcc/config/arm/bpabi.h                    |    4 -

>  gcc/config/arm/elf.h                      |    6 +-

>  gcc/config/arm/linux-elf.h                |    3 -

>  gcc/config/arm/netbsd-elf.h               |    4 -

>  gcc/config/arm/parsecpu.awk               |  295 +++-

>  gcc/config/arm/t-aprofile                 |  200 +--

>  gcc/config/arm/t-arm-elf                  |  173 +-

>  gcc/config/arm/t-fuchsia                  |   33 +

>  gcc/config/arm/t-linux-eabi               |    4 +

>  gcc/config/arm/t-multilib                 |  126 +-

>  gcc/config/arm/t-phoenix                  |   20 +-

>  gcc/config/arm/t-rmprofile                |  147 +-

>  gcc/config/arm/t-rtems                    |   49 +-

>  gcc/config/arm/t-symbian                  |   34 +-

>  gcc/config/arm/vxworks.h                  |    2 -

>  gcc/doc/fragments.texi                    |   10 +-

>  gcc/doc/invoke.texi                       |  371 ++++-

>  gcc/genmultilib                           |    4 +-

>  gcc/testsuite/gcc.dg/pr59418.c            |    2 +-

>  gcc/testsuite/gcc.target/arm/multilib.exp |  685 ++++++++

>  gcc/testsuite/gcc.target/arm/pr51915.c    |    2 +-

>  gcc/testsuite/gcc.target/arm/pr52006.c    |    2 +-

>  gcc/testsuite/gcc.target/arm/pr53187.c    |    2 +-

>  libgcc/config/arm/cmse_nonsecure_call.S   |    8 +

>  38 files changed, 5073 insertions(+), 2440 deletions(-)

>  create mode 100644 gcc/config/arm/t-fuchsia

>  create mode 100644 gcc/testsuite/gcc.target/arm/multilib.exp

>

> ----------------2.7.4--

>


I wanted to run a validation with the full series applied as one patch
over r249050,
so I just downloaded all the patches, concatenated them in order, but the result
fails to apply. (conflicts with arm-cpu-cdata.h, arm-cpus.in,
t-aprofile, t-rmprofile)

Am I missing something?

Thanks,

Christophe
Richard Earnshaw (lists) June 9, 2017, 11:27 p.m. UTC | #2
On 09/06/17 23:45, Christophe Lyon wrote:
> Hi Richard,

> 

> 

> On 9 June 2017 at 14:53, Richard Earnshaw <Richard.Earnshaw@arm.com> wrote:

>>

>> During the ARM BoF at the Cauldron last year I mentioned that I wanted

>> to rework the way GCC on ARM handles the command line options.  The

>> problem was that most users, and even many experts, can't remember

>> which FPU/SIMD unit comes with which CPU and that consequently many

>> users were inadvertenly generating sub-optimal code for their system.

>>

>> This patch series implements the proposed change and provides support

>> for a generic way of adding optional features to architectures and CPU

>> names.  The documentation patches at the end of the series explain the

>> new syntax, so I won't repeat all that here.  Suffice to say here that

>> the result is that the -mfpu option now defaults to 'auto', which

>> allows the compiler to infer the floating-point and simd options from

>> the CPU/architecture options and that these options can normally be

>> expressed in a context-specific manner like +simd or +fp without

>> having to know precisely which variant is implemented.  Long term I'd

>> like to deprecate -mfpu and entirely move over to the new syntax; but

>> it's too early to start that process now.

>>

>> All the patches in the series should build a working basic compiler,

>> but the multilib selection will not work correctly until the relevant

>> patches towards the end are applied.  It is not really feasible to

>> retain that functionality without collapsing too many of the patches

>> together into one hunk.  It's also possible that some tests in the

>> testsuite may exhibit transient misbehaviour, but there should be no

>> regressions by the end of the sequence (some tests no-longer run in

>> the default configurations because the default CPU does not have

>> floating-point support).

>>

>> Just two patches are to the generic code, but both are fairly trivial.

>> One permits the sbitmap code to be used in the driver programs and the

>> other provides a way of escaping the meta-character in some multilib

>> reuse strings.

>>

>> I won't apply any of this series until those two patches have been

>> approved, and I won't commit anything before the middle of next week

>> even then.  This is a fairly complex change and it deserves some time

>> for people to comment before committing.

>>

>> R.

>>

>> Richard Earnshaw (30):

>>   [arm] Use strings for -march, -mcpu and -mtune options

>>   [arm] Rewrite -march and -mcpu options for passing to the assembler

>>   [arm] Don't pass -mfpu=auto through to the assembler.

>>   [arm] Allow +opt on arbitrary cpu and architecture specifications

>>   [arm] Add architectural options

>>   [arm] Add default FPUs for CPUs.

>>   [build] Make sbitmap code available to the driver programs

>>   [arm] Split CPU, architecture and tuning data tables.

>>   [ARM] Move cpu and architecture option name parsing code to

>>     arm-common.c

>>   [arm] Use standard option parsing code for detecting thumb-only

>>     targets

>>   [arm] Allow CPU and architecture extensions to be defined as aliases

>>   [arm] Allow new extended syntax CPU and architecture names during

>>     configure

>>   [arm] Force a CPU default in the config args defaults list.

>>   [arm] Generate a canonical form for -march

>>   [arm] Make -mfloat-abi=softfp work when there are no FPU instructions

>>   [arm] Update basic multilib configuration

>>   [arm] Make 'auto' the default FPU selection option.

>>   [arm] Rewrite t-aprofile using new selector methodology

>>   [arm] Explicitly set .fpu in cmse_nonsecure_call.S

>>   [genmultilib] Allow explicit periods to be escaped in MULTILIB_REUSE

>>   [arm][testsuite] Use -march=armv7-a+fp when testing hard-float ABI.

>>   [arm] Rewrite t-rmprofile multilib specification

>>   [arm][rtems] Update t-rtems for new option framework

>>   [arm][linux-eabi] Ensure all multilib variables are reset

>>   [arm][phoenix] reset all multilib variables

>>   [arm] Rework multlib builds for symbianelf

>>   [arm][fuchsia] Rework multilib support

>>   [arm] Add a few missing architecture extension options.

>>   [arm][doc] Document new -march= syntax.

>>   [arm][doc] Document changes to -mcpu, -mtune and -mfpu.

>>

>>  gcc/Makefile.in                           |    2 +-

>>  gcc/common/config/arm/arm-common.c        |  651 +++++++-

>>  gcc/config.gcc                            |   17 +-

>>  gcc/config/arm/arm-builtins.c             |    4 +-

>>  gcc/config/arm/arm-cpu-cdata.h            | 2444 +++++++++++++++++++++++------

>>  gcc/config/arm/arm-cpu-data.h             | 1410 ++---------------

>>  gcc/config/arm/arm-cpu.h                  |   38 +

>>  gcc/config/arm/arm-cpus.in                |  237 ++-

>>  gcc/config/arm/arm-isa.h                  |   20 +-

>>  gcc/config/arm/arm-protos.h               |   56 +-

>>  gcc/config/arm/arm-tables.opt             |   21 +-

>>  gcc/config/arm/arm.c                      |  337 ++--

>>  gcc/config/arm/arm.h                      |   75 +-

>>  gcc/config/arm/arm.opt                    |   15 +-

>>  gcc/config/arm/bpabi.h                    |    4 -

>>  gcc/config/arm/elf.h                      |    6 +-

>>  gcc/config/arm/linux-elf.h                |    3 -

>>  gcc/config/arm/netbsd-elf.h               |    4 -

>>  gcc/config/arm/parsecpu.awk               |  295 +++-

>>  gcc/config/arm/t-aprofile                 |  200 +--

>>  gcc/config/arm/t-arm-elf                  |  173 +-

>>  gcc/config/arm/t-fuchsia                  |   33 +

>>  gcc/config/arm/t-linux-eabi               |    4 +

>>  gcc/config/arm/t-multilib                 |  126 +-

>>  gcc/config/arm/t-phoenix                  |   20 +-

>>  gcc/config/arm/t-rmprofile                |  147 +-

>>  gcc/config/arm/t-rtems                    |   49 +-

>>  gcc/config/arm/t-symbian                  |   34 +-

>>  gcc/config/arm/vxworks.h                  |    2 -

>>  gcc/doc/fragments.texi                    |   10 +-

>>  gcc/doc/invoke.texi                       |  371 ++++-

>>  gcc/genmultilib                           |    4 +-

>>  gcc/testsuite/gcc.dg/pr59418.c            |    2 +-

>>  gcc/testsuite/gcc.target/arm/multilib.exp |  685 ++++++++

>>  gcc/testsuite/gcc.target/arm/pr51915.c    |    2 +-

>>  gcc/testsuite/gcc.target/arm/pr52006.c    |    2 +-

>>  gcc/testsuite/gcc.target/arm/pr53187.c    |    2 +-

>>  libgcc/config/arm/cmse_nonsecure_call.S   |    8 +

>>  38 files changed, 5073 insertions(+), 2440 deletions(-)

>>  create mode 100644 gcc/config/arm/t-fuchsia

>>  create mode 100644 gcc/testsuite/gcc.target/arm/multilib.exp

>>

>> ----------------2.7.4--

>>

> 

> I wanted to run a validation with the full series applied as one patch

> over r249050,

> so I just downloaded all the patches, concatenated them in order, but the result

> fails to apply. (conflicts with arm-cpu-cdata.h, arm-cpus.in,

> t-aprofile, t-rmprofile)

> 

> Am I missing something?

> 

> Thanks,

> 

> Christophe

> 


I really appreciate you trying to do this...

I rebased the patch series sometime on Tuesday/Wednesday just before Jim
Wilson committed his falkor change; you'll need to back out to just
before r248944.  I can't think of anything else that might have just
gone in that might conflict.  For arm-cpu-cdata.h (and the other
auto-generated files, like arm-cpu-data.h) you can just delete the file
and it will be rebuilt automatically, the others really do need the
conflict to be resolved.

Obviously I'll rebase again just before the commit, but propagating such
changes through the patch series is quite tedious and I don't want to do
it any more than necessary :-).

It would be easier if the generated files weren't checked in to the
repository...

R.
Nathan Sidwell June 12, 2017, 11:48 a.m. UTC | #3
On 06/09/2017 08:53 AM, Richard Earnshaw wrote:

> This patch series implements the proposed change and provides support

> for a generic way of adding optional features to architectures and CPU

> names.  The documentation patches at the end of the series explain the

> new syntax, so I won't repeat all that here.  Suffice to say here that

> the result is that the -mfpu option now defaults to 'auto', which

> allows the compiler to infer the floating-point and simd options from

> the CPU/architecture options and that these options can normally be

> expressed in a context-specific manner like +simd or +fp without

> having to know precisely which variant is implemented.


Hallelujah!

-- 
Nathan Sidwell
Christophe Lyon June 12, 2017, 11:49 a.m. UTC | #4
On 10 June 2017 at 01:27, Richard Earnshaw (lists)
<Richard.Earnshaw@arm.com> wrote:
> On 09/06/17 23:45, Christophe Lyon wrote:

>> Hi Richard,

>>

>>

>> On 9 June 2017 at 14:53, Richard Earnshaw <Richard.Earnshaw@arm.com> wrote:

>>>

>>> During the ARM BoF at the Cauldron last year I mentioned that I wanted

>>> to rework the way GCC on ARM handles the command line options.  The

>>> problem was that most users, and even many experts, can't remember

>>> which FPU/SIMD unit comes with which CPU and that consequently many

>>> users were inadvertenly generating sub-optimal code for their system.

>>>

>>> This patch series implements the proposed change and provides support

>>> for a generic way of adding optional features to architectures and CPU

>>> names.  The documentation patches at the end of the series explain the

>>> new syntax, so I won't repeat all that here.  Suffice to say here that

>>> the result is that the -mfpu option now defaults to 'auto', which

>>> allows the compiler to infer the floating-point and simd options from

>>> the CPU/architecture options and that these options can normally be

>>> expressed in a context-specific manner like +simd or +fp without

>>> having to know precisely which variant is implemented.  Long term I'd

>>> like to deprecate -mfpu and entirely move over to the new syntax; but

>>> it's too early to start that process now.

>>>

>>> All the patches in the series should build a working basic compiler,

>>> but the multilib selection will not work correctly until the relevant

>>> patches towards the end are applied.  It is not really feasible to

>>> retain that functionality without collapsing too many of the patches

>>> together into one hunk.  It's also possible that some tests in the

>>> testsuite may exhibit transient misbehaviour, but there should be no

>>> regressions by the end of the sequence (some tests no-longer run in

>>> the default configurations because the default CPU does not have

>>> floating-point support).

>>>

>>> Just two patches are to the generic code, but both are fairly trivial.

>>> One permits the sbitmap code to be used in the driver programs and the

>>> other provides a way of escaping the meta-character in some multilib

>>> reuse strings.

>>>

>>> I won't apply any of this series until those two patches have been

>>> approved, and I won't commit anything before the middle of next week

>>> even then.  This is a fairly complex change and it deserves some time

>>> for people to comment before committing.

>>>

>>> R.

>>>

>>> Richard Earnshaw (30):

>>>   [arm] Use strings for -march, -mcpu and -mtune options

>>>   [arm] Rewrite -march and -mcpu options for passing to the assembler

>>>   [arm] Don't pass -mfpu=auto through to the assembler.

>>>   [arm] Allow +opt on arbitrary cpu and architecture specifications

>>>   [arm] Add architectural options

>>>   [arm] Add default FPUs for CPUs.

>>>   [build] Make sbitmap code available to the driver programs

>>>   [arm] Split CPU, architecture and tuning data tables.

>>>   [ARM] Move cpu and architecture option name parsing code to

>>>     arm-common.c

>>>   [arm] Use standard option parsing code for detecting thumb-only

>>>     targets

>>>   [arm] Allow CPU and architecture extensions to be defined as aliases

>>>   [arm] Allow new extended syntax CPU and architecture names during

>>>     configure

>>>   [arm] Force a CPU default in the config args defaults list.

>>>   [arm] Generate a canonical form for -march

>>>   [arm] Make -mfloat-abi=softfp work when there are no FPU instructions

>>>   [arm] Update basic multilib configuration

>>>   [arm] Make 'auto' the default FPU selection option.

>>>   [arm] Rewrite t-aprofile using new selector methodology

>>>   [arm] Explicitly set .fpu in cmse_nonsecure_call.S

>>>   [genmultilib] Allow explicit periods to be escaped in MULTILIB_REUSE

>>>   [arm][testsuite] Use -march=armv7-a+fp when testing hard-float ABI.

>>>   [arm] Rewrite t-rmprofile multilib specification

>>>   [arm][rtems] Update t-rtems for new option framework

>>>   [arm][linux-eabi] Ensure all multilib variables are reset

>>>   [arm][phoenix] reset all multilib variables

>>>   [arm] Rework multlib builds for symbianelf

>>>   [arm][fuchsia] Rework multilib support

>>>   [arm] Add a few missing architecture extension options.

>>>   [arm][doc] Document new -march= syntax.

>>>   [arm][doc] Document changes to -mcpu, -mtune and -mfpu.

>>>

>>>  gcc/Makefile.in                           |    2 +-

>>>  gcc/common/config/arm/arm-common.c        |  651 +++++++-

>>>  gcc/config.gcc                            |   17 +-

>>>  gcc/config/arm/arm-builtins.c             |    4 +-

>>>  gcc/config/arm/arm-cpu-cdata.h            | 2444 +++++++++++++++++++++++------

>>>  gcc/config/arm/arm-cpu-data.h             | 1410 ++---------------

>>>  gcc/config/arm/arm-cpu.h                  |   38 +

>>>  gcc/config/arm/arm-cpus.in                |  237 ++-

>>>  gcc/config/arm/arm-isa.h                  |   20 +-

>>>  gcc/config/arm/arm-protos.h               |   56 +-

>>>  gcc/config/arm/arm-tables.opt             |   21 +-

>>>  gcc/config/arm/arm.c                      |  337 ++--

>>>  gcc/config/arm/arm.h                      |   75 +-

>>>  gcc/config/arm/arm.opt                    |   15 +-

>>>  gcc/config/arm/bpabi.h                    |    4 -

>>>  gcc/config/arm/elf.h                      |    6 +-

>>>  gcc/config/arm/linux-elf.h                |    3 -

>>>  gcc/config/arm/netbsd-elf.h               |    4 -

>>>  gcc/config/arm/parsecpu.awk               |  295 +++-

>>>  gcc/config/arm/t-aprofile                 |  200 +--

>>>  gcc/config/arm/t-arm-elf                  |  173 +-

>>>  gcc/config/arm/t-fuchsia                  |   33 +

>>>  gcc/config/arm/t-linux-eabi               |    4 +

>>>  gcc/config/arm/t-multilib                 |  126 +-

>>>  gcc/config/arm/t-phoenix                  |   20 +-

>>>  gcc/config/arm/t-rmprofile                |  147 +-

>>>  gcc/config/arm/t-rtems                    |   49 +-

>>>  gcc/config/arm/t-symbian                  |   34 +-

>>>  gcc/config/arm/vxworks.h                  |    2 -

>>>  gcc/doc/fragments.texi                    |   10 +-

>>>  gcc/doc/invoke.texi                       |  371 ++++-

>>>  gcc/genmultilib                           |    4 +-

>>>  gcc/testsuite/gcc.dg/pr59418.c            |    2 +-

>>>  gcc/testsuite/gcc.target/arm/multilib.exp |  685 ++++++++

>>>  gcc/testsuite/gcc.target/arm/pr51915.c    |    2 +-

>>>  gcc/testsuite/gcc.target/arm/pr52006.c    |    2 +-

>>>  gcc/testsuite/gcc.target/arm/pr53187.c    |    2 +-

>>>  libgcc/config/arm/cmse_nonsecure_call.S   |    8 +

>>>  38 files changed, 5073 insertions(+), 2440 deletions(-)

>>>  create mode 100644 gcc/config/arm/t-fuchsia

>>>  create mode 100644 gcc/testsuite/gcc.target/arm/multilib.exp

>>>

>>> ----------------2.7.4--

>>>

>>

>> I wanted to run a validation with the full series applied as one patch

>> over r249050,

>> so I just downloaded all the patches, concatenated them in order, but the result

>> fails to apply. (conflicts with arm-cpu-cdata.h, arm-cpus.in,

>> t-aprofile, t-rmprofile)

>>

>> Am I missing something?

>>

>> Thanks,

>>

>> Christophe

>>

>

> I really appreciate you trying to do this...

>

> I rebased the patch series sometime on Tuesday/Wednesday just before Jim

> Wilson committed his falkor change; you'll need to back out to just

> before r248944.  I can't think of anything else that might have just

> gone in that might conflict.  For arm-cpu-cdata.h (and the other

> auto-generated files, like arm-cpu-data.h) you can just delete the file

> and it will be rebuilt automatically, the others really do need the

> conflict to be resolved.

>

> Obviously I'll rebase again just before the commit, but propagating such

> changes through the patch series is quite tedious and I don't want to do

> it any more than necessary :-).

>

> It would be easier if the generated files weren't checked in to the

> repository...

>

> R.


Hi Richard,

Starting a validation of the whole patch against r248942 did work, thanks.

The results are here:
http://people.linaro.org/~christophe.lyon/cross-validation/gcc-test-patches/248942-rework-cpu-arch-fpu.patch/report-build-info.html

Regressions are detected in many configurations, unfortunately.
Some may be caused by the fact that I've upgraded to dejagnu-1.6+ for
my testing,
and thus "multilib flags" are now prepended rather than appended, but
I don't think that's the majority.

To help you understand/group all the reports:
- all "arm-none-linux-gnueabi" with REGRESSED now have:
FAIL: gcc.target/arm/neon-thumb2-move.c (test for excess errors)
FAIL: gcc.target/arm/no-volatile-in-it.c scan-assembler-not ldrgt
- same for the 2 configs arm-none-eabi --with-cpu=cortex-a9

- all "arm-none-linux-gnueabihf" and "armeb-none-linux-gnueabihf" with
REGRESSED now have:
FAIL: gcc.target/arm/no-volatile-in-it.c scan-assembler-not ldrgt

- arm-none-eabi --with-cpu=cortex-m3 now has:
FAIL:
    gcc.target/arm/no-volatile-in-it.c scan-assembler-not ldrgt
    gcc.target/arm/thumb2-slow-flash-data-2.c (test for excess errors)
    gcc.target/arm/thumb2-slow-flash-data-3.c (test for excess errors)
    gcc.target/arm/thumb2-slow-flash-data-4.c (test for excess errors)
    gcc.target/arm/thumb2-slow-flash-data-5.c (test for excess errors)
UNRESOLVED:
    gcc.target/arm/thumb2-slow-flash-data-4.c scan-assembler-times #1\\.0e\\+0 3
    gcc.target/arm/thumb2-slow-flash-data-5.c scan-assembler-not #1\\.0e\\+0

- The 2 cells with "BIG-REG" mean regressions where detected, but the report
is >100kb so it was attached as a .xz file, click on 'BIG-REG" to download it.

- the cells with "BETTER" can be questionable: it means no new failure
appeared, but PASS -> UNSUPPORTED is considered as "better". Here
we have cases with several thousands (!) of tests becoming unsupported,
which looks a bit suspicious.

Among other things, I've noticed that when passing -march=armv5t,
arm_neon_ok fails:
xgcc -march=armv5t -fno-diagnostics-show-caret
-fdiagnostics-color=never -mfpu=neon -mfloat-abi=softfp -march=
armv7-a -c -o arm_neon_ok15574.o arm_neon_ok15574.c
arm_neon_ok15574.c:9:4: error: #error Architecture does not support NEON.
compiler exited with status 1

I'd expect -march=armv7-a to allow to use -mfpu=neon?

Regarding the new multilib.exp tests introduced by the patch, my testing
did not run it because I have no configuration setting aprofile or rmprofile.
Maybe it's time I add one, or update the existing ones.
I didn't see any message "skipping multilib tests due to
multilib_flags setting",
but I guess that's because my runs are not verbose enough. That being said,
I'm not sure how the multilib_flags are set in board_info? Is that derived from
RUNTESTFLAGS?

From this report page, you can also click on "sum" and "log" (when
present) to download the gcc.sum or gcc.log files.

Feel free to ask more details if I haven't been clear enough.

Thanks,

Christophe
Richard Earnshaw (lists) June 12, 2017, 2:34 p.m. UTC | #5
On 12/06/17 12:49, Christophe Lyon wrote:
> On 10 June 2017 at 01:27, Richard Earnshaw (lists)

> <Richard.Earnshaw@arm.com> wrote:

>> On 09/06/17 23:45, Christophe Lyon wrote:

>>> Hi Richard,

>>>

>>>

>>> On 9 June 2017 at 14:53, Richard Earnshaw <Richard.Earnshaw@arm.com> wrote:

>>>>

>>>> During the ARM BoF at the Cauldron last year I mentioned that I wanted

>>>> to rework the way GCC on ARM handles the command line options.  The

>>>> problem was that most users, and even many experts, can't remember

>>>> which FPU/SIMD unit comes with which CPU and that consequently many

>>>> users were inadvertenly generating sub-optimal code for their system.

>>>>

>>>> This patch series implements the proposed change and provides support

>>>> for a generic way of adding optional features to architectures and CPU

>>>> names.  The documentation patches at the end of the series explain the

>>>> new syntax, so I won't repeat all that here.  Suffice to say here that

>>>> the result is that the -mfpu option now defaults to 'auto', which

>>>> allows the compiler to infer the floating-point and simd options from

>>>> the CPU/architecture options and that these options can normally be

>>>> expressed in a context-specific manner like +simd or +fp without

>>>> having to know precisely which variant is implemented.  Long term I'd

>>>> like to deprecate -mfpu and entirely move over to the new syntax; but

>>>> it's too early to start that process now.

>>>>

>>>> All the patches in the series should build a working basic compiler,

>>>> but the multilib selection will not work correctly until the relevant

>>>> patches towards the end are applied.  It is not really feasible to

>>>> retain that functionality without collapsing too many of the patches

>>>> together into one hunk.  It's also possible that some tests in the

>>>> testsuite may exhibit transient misbehaviour, but there should be no

>>>> regressions by the end of the sequence (some tests no-longer run in

>>>> the default configurations because the default CPU does not have

>>>> floating-point support).

>>>>

>>>> Just two patches are to the generic code, but both are fairly trivial.

>>>> One permits the sbitmap code to be used in the driver programs and the

>>>> other provides a way of escaping the meta-character in some multilib

>>>> reuse strings.

>>>>

>>>> I won't apply any of this series until those two patches have been

>>>> approved, and I won't commit anything before the middle of next week

>>>> even then.  This is a fairly complex change and it deserves some time

>>>> for people to comment before committing.

>>>>

>>>> R.

>>>>

>>>> Richard Earnshaw (30):

>>>>   [arm] Use strings for -march, -mcpu and -mtune options

>>>>   [arm] Rewrite -march and -mcpu options for passing to the assembler

>>>>   [arm] Don't pass -mfpu=auto through to the assembler.

>>>>   [arm] Allow +opt on arbitrary cpu and architecture specifications

>>>>   [arm] Add architectural options

>>>>   [arm] Add default FPUs for CPUs.

>>>>   [build] Make sbitmap code available to the driver programs

>>>>   [arm] Split CPU, architecture and tuning data tables.

>>>>   [ARM] Move cpu and architecture option name parsing code to

>>>>     arm-common.c

>>>>   [arm] Use standard option parsing code for detecting thumb-only

>>>>     targets

>>>>   [arm] Allow CPU and architecture extensions to be defined as aliases

>>>>   [arm] Allow new extended syntax CPU and architecture names during

>>>>     configure

>>>>   [arm] Force a CPU default in the config args defaults list.

>>>>   [arm] Generate a canonical form for -march

>>>>   [arm] Make -mfloat-abi=softfp work when there are no FPU instructions

>>>>   [arm] Update basic multilib configuration

>>>>   [arm] Make 'auto' the default FPU selection option.

>>>>   [arm] Rewrite t-aprofile using new selector methodology

>>>>   [arm] Explicitly set .fpu in cmse_nonsecure_call.S

>>>>   [genmultilib] Allow explicit periods to be escaped in MULTILIB_REUSE

>>>>   [arm][testsuite] Use -march=armv7-a+fp when testing hard-float ABI.

>>>>   [arm] Rewrite t-rmprofile multilib specification

>>>>   [arm][rtems] Update t-rtems for new option framework

>>>>   [arm][linux-eabi] Ensure all multilib variables are reset

>>>>   [arm][phoenix] reset all multilib variables

>>>>   [arm] Rework multlib builds for symbianelf

>>>>   [arm][fuchsia] Rework multilib support

>>>>   [arm] Add a few missing architecture extension options.

>>>>   [arm][doc] Document new -march= syntax.

>>>>   [arm][doc] Document changes to -mcpu, -mtune and -mfpu.

>>>>

>>>>  gcc/Makefile.in                           |    2 +-

>>>>  gcc/common/config/arm/arm-common.c        |  651 +++++++-

>>>>  gcc/config.gcc                            |   17 +-

>>>>  gcc/config/arm/arm-builtins.c             |    4 +-

>>>>  gcc/config/arm/arm-cpu-cdata.h            | 2444 +++++++++++++++++++++++------

>>>>  gcc/config/arm/arm-cpu-data.h             | 1410 ++---------------

>>>>  gcc/config/arm/arm-cpu.h                  |   38 +

>>>>  gcc/config/arm/arm-cpus.in                |  237 ++-

>>>>  gcc/config/arm/arm-isa.h                  |   20 +-

>>>>  gcc/config/arm/arm-protos.h               |   56 +-

>>>>  gcc/config/arm/arm-tables.opt             |   21 +-

>>>>  gcc/config/arm/arm.c                      |  337 ++--

>>>>  gcc/config/arm/arm.h                      |   75 +-

>>>>  gcc/config/arm/arm.opt                    |   15 +-

>>>>  gcc/config/arm/bpabi.h                    |    4 -

>>>>  gcc/config/arm/elf.h                      |    6 +-

>>>>  gcc/config/arm/linux-elf.h                |    3 -

>>>>  gcc/config/arm/netbsd-elf.h               |    4 -

>>>>  gcc/config/arm/parsecpu.awk               |  295 +++-

>>>>  gcc/config/arm/t-aprofile                 |  200 +--

>>>>  gcc/config/arm/t-arm-elf                  |  173 +-

>>>>  gcc/config/arm/t-fuchsia                  |   33 +

>>>>  gcc/config/arm/t-linux-eabi               |    4 +

>>>>  gcc/config/arm/t-multilib                 |  126 +-

>>>>  gcc/config/arm/t-phoenix                  |   20 +-

>>>>  gcc/config/arm/t-rmprofile                |  147 +-

>>>>  gcc/config/arm/t-rtems                    |   49 +-

>>>>  gcc/config/arm/t-symbian                  |   34 +-

>>>>  gcc/config/arm/vxworks.h                  |    2 -

>>>>  gcc/doc/fragments.texi                    |   10 +-

>>>>  gcc/doc/invoke.texi                       |  371 ++++-

>>>>  gcc/genmultilib                           |    4 +-

>>>>  gcc/testsuite/gcc.dg/pr59418.c            |    2 +-

>>>>  gcc/testsuite/gcc.target/arm/multilib.exp |  685 ++++++++

>>>>  gcc/testsuite/gcc.target/arm/pr51915.c    |    2 +-

>>>>  gcc/testsuite/gcc.target/arm/pr52006.c    |    2 +-

>>>>  gcc/testsuite/gcc.target/arm/pr53187.c    |    2 +-

>>>>  libgcc/config/arm/cmse_nonsecure_call.S   |    8 +

>>>>  38 files changed, 5073 insertions(+), 2440 deletions(-)

>>>>  create mode 100644 gcc/config/arm/t-fuchsia

>>>>  create mode 100644 gcc/testsuite/gcc.target/arm/multilib.exp

>>>>

>>>> ----------------2.7.4--

>>>>

>>>

>>> I wanted to run a validation with the full series applied as one patch

>>> over r249050,

>>> so I just downloaded all the patches, concatenated them in order, but the result

>>> fails to apply. (conflicts with arm-cpu-cdata.h, arm-cpus.in,

>>> t-aprofile, t-rmprofile)

>>>

>>> Am I missing something?

>>>

>>> Thanks,

>>>

>>> Christophe

>>>

>>

>> I really appreciate you trying to do this...

>>

>> I rebased the patch series sometime on Tuesday/Wednesday just before Jim

>> Wilson committed his falkor change; you'll need to back out to just

>> before r248944.  I can't think of anything else that might have just

>> gone in that might conflict.  For arm-cpu-cdata.h (and the other

>> auto-generated files, like arm-cpu-data.h) you can just delete the file

>> and it will be rebuilt automatically, the others really do need the

>> conflict to be resolved.

>>

>> Obviously I'll rebase again just before the commit, but propagating such

>> changes through the patch series is quite tedious and I don't want to do

>> it any more than necessary :-).

>>

>> It would be easier if the generated files weren't checked in to the

>> repository...

>>

>> R.

> 

> Hi Richard,

> 

> Starting a validation of the whole patch against r248942 did work, thanks.

> 

> The results are here:

> http://people.linaro.org/~christophe.lyon/cross-validation/gcc-test-patches/248942-rework-cpu-arch-fpu.patch/report-build-info.html

> 

> Regressions are detected in many configurations, unfortunately.

> Some may be caused by the fact that I've upgraded to dejagnu-1.6+ for

> my testing,

> and thus "multilib flags" are now prepended rather than appended, but

> I don't think that's the majority.

> 

> To help you understand/group all the reports:

> - all "arm-none-linux-gnueabi" with REGRESSED now have:

> FAIL: gcc.target/arm/neon-thumb2-move.c (test for excess errors)


See later.

> FAIL: gcc.target/arm/no-volatile-in-it.c scan-assembler-not ldrgt

> - same for the 2 configs arm-none-eabi --with-cpu=cortex-a9


I'm checking a fix for this, I think I understand what's going on here.

> 

> - all "arm-none-linux-gnueabihf" and "armeb-none-linux-gnueabihf" with

> REGRESSED now have:

> FAIL: gcc.target/arm/no-volatile-in-it.c scan-assembler-not ldrgt

> 

> - arm-none-eabi --with-cpu=cortex-m3 now has:

> FAIL:

>     gcc.target/arm/no-volatile-in-it.c scan-assembler-not ldrgt

>     gcc.target/arm/thumb2-slow-flash-data-2.c (test for excess errors)

>     gcc.target/arm/thumb2-slow-flash-data-3.c (test for excess errors)

>     gcc.target/arm/thumb2-slow-flash-data-4.c (test for excess errors)

>     gcc.target/arm/thumb2-slow-flash-data-5.c (test for excess errors)

> UNRESOLVED:

>     gcc.target/arm/thumb2-slow-flash-data-4.c scan-assembler-times #1\\.0e\\+0 3

>     gcc.target/arm/thumb2-slow-flash-data-5.c scan-assembler-not #1\\.0e\\+0

> 

> - The 2 cells with "BIG-REG" mean regressions where detected, but the report

> is >100kb so it was attached as a .xz file, click on 'BIG-REG" to download it.

> 

> - the cells with "BETTER" can be questionable: it means no new failure

> appeared, but PASS -> UNSUPPORTED is considered as "better". Here

> we have cases with several thousands (!) of tests becoming unsupported,

> which looks a bit suspicious.

> 

> Among other things, I've noticed that when passing -march=armv5t,

> arm_neon_ok fails:

> xgcc -march=armv5t -fno-diagnostics-show-caret

> -fdiagnostics-color=never -mfpu=neon -mfloat-abi=softfp -march=

> armv7-a -c -o arm_neon_ok15574.o arm_neon_ok15574.c

> arm_neon_ok15574.c:9:4: error: #error Architecture does not support NEON.

> compiler exited with status 1

> 

> I'd expect -march=armv7-a to allow to use -mfpu=neon?

> 


It does.  The problem seems to be a generic one in the driver in that
the rewrite rules are always passed the first instance of -march and not
the last.  Indeed, with the aarch64 compiler, if I write

gcc -mcpu=native -mcpu=cortex-a53

then the driver will rewrite this as

./cc1 -mcpu=cortex-a53 -mcpu=<expansion of native cpu name>

which doesn't seem to be the right thing at all.

So we either have a generic problem with all option rewriting, or there
are some subtle details of it that we've not figured out yet.

Joseph, is there a way to get the rewrite rules to receive the *last*
instance of a flag rather than the first?  Or is the current behaviour
simply wrong?

R.

> Regarding the new multilib.exp tests introduced by the patch, my testing

> did not run it because I have no configuration setting aprofile or rmprofile.

> Maybe it's time I add one, or update the existing ones.

> I didn't see any message "skipping multilib tests due to

> multilib_flags setting",

> but I guess that's because my runs are not verbose enough. That being said,

> I'm not sure how the multilib_flags are set in board_info? Is that derived from

> RUNTESTFLAGS?

> 

> From this report page, you can also click on "sum" and "log" (when

> present) to download the gcc.sum or gcc.log files.

> 

> Feel free to ask more details if I haven't been clear enough.

> 

> Thanks,

> 

> Christophe

>
Joseph Myers June 12, 2017, 5:11 p.m. UTC | #6
On Mon, 12 Jun 2017, Richard Earnshaw (lists) wrote:

> It does.  The problem seems to be a generic one in the driver in that

> the rewrite rules are always passed the first instance of -march and not

> the last.  Indeed, with the aarch64 compiler, if I write

> 

> gcc -mcpu=native -mcpu=cortex-a53

> 

> then the driver will rewrite this as

> 

> ./cc1 -mcpu=cortex-a53 -mcpu=<expansion of native cpu name>

> 

> which doesn't seem to be the right thing at all.

> 

> So we either have a generic problem with all option rewriting, or there

> are some subtle details of it that we've not figured out yet.

> 

> Joseph, is there a way to get the rewrite rules to receive the *last*

> instance of a flag rather than the first?  Or is the current behaviour

> simply wrong?


I think there are at least two separate issues here.

In the AArch64 port (and other ports), the specs for -mcpu=native use 
%{mcpu=native:%<mcpu=native %:local_cpu_detect(cpu)} as part of 
DRIVER_SELF_SPECS.  Options added by DRIVER_SELF_SPECS are added at the 
end of the command line (after OPTION_DEFAULT_SPECS has been processed).  
Thus, if there is any -mcpu=native option, the options from generated by 
local_cpu_detect will be added.

In patch 14 of this series, you have specs of the form %{mcpu=*: cpu %*} 
inside a canon_arch call.  According to the comment in gcc.c documenting 
specs

 %{S*:X}  substitutes X if one or more switches whose names start
          with -S was given to GCC.  Normally X is substituted only
          once, no matter how many such switches appeared.  However,
          if %* appears somewhere in X, then X will be substituted
          once for each matching switch, with the %* replaced by the
          part of that switch that matched the '*'.  A space will be
          appended after the last substition unless there is more
          text in current sequence.

this ought to mean that every -mcpu= option results in a corresponding cpu 
<something> in the arguments to canon_arch (in the same order as the 
original options).  If it doesn't, that sounds like a bug in the %* 
handling.

Overridden options can be removed before specs processing if a cycle of 
options is marked with Negative in the .opt files (see prune_options), but 
that doesn't apply to options with arguments.  If you had a system for 
pruning e.g. all but the last -mcpu= option (for options where it's just 
the last argument that matters), you'd also want to make sure that prior 
options do still generate errors if the option argument is invalid.

-- 
Joseph S. Myers
joseph@codesourcery.com
Richard Earnshaw (lists) June 12, 2017, 9:27 p.m. UTC | #7
On 12/06/17 18:11, Joseph Myers wrote:
> On Mon, 12 Jun 2017, Richard Earnshaw (lists) wrote:

> 

>> It does.  The problem seems to be a generic one in the driver in that

>> the rewrite rules are always passed the first instance of -march and not

>> the last.  Indeed, with the aarch64 compiler, if I write

>>

>> gcc -mcpu=native -mcpu=cortex-a53

>>

>> then the driver will rewrite this as

>>

>> ./cc1 -mcpu=cortex-a53 -mcpu=<expansion of native cpu name>

>>

>> which doesn't seem to be the right thing at all.

>>

>> So we either have a generic problem with all option rewriting, or there

>> are some subtle details of it that we've not figured out yet.

>>

>> Joseph, is there a way to get the rewrite rules to receive the *last*

>> instance of a flag rather than the first?  Or is the current behaviour

>> simply wrong?

> 

> I think there are at least two separate issues here.

> 

> In the AArch64 port (and other ports), the specs for -mcpu=native use 

> %{mcpu=native:%<mcpu=native %:local_cpu_detect(cpu)} as part of 

> DRIVER_SELF_SPECS.  Options added by DRIVER_SELF_SPECS are added at the 

> end of the command line (after OPTION_DEFAULT_SPECS has been processed).  

> Thus, if there is any -mcpu=native option, the options from generated by 

> local_cpu_detect will be added.

> 


Yes, this seems like a bug in all implementations of native detect
routines.  To make the behaviour sane I think they will all need to be
reworked to pass all relevant -m<opt>= variants into some code that
checks first that "native" is the last option and only then to apply the
substitution.

> In patch 14 of this series, you have specs of the form %{mcpu=*: cpu %*} 

> inside a canon_arch call.  According to the comment in gcc.c documenting 

> specs

> 

>  %{S*:X}  substitutes X if one or more switches whose names start

>           with -S was given to GCC.  Normally X is substituted only

>           once, no matter how many such switches appeared.  However,

>           if %* appears somewhere in X, then X will be substituted

>           once for each matching switch, with the %* replaced by the

>           part of that switch that matched the '*'.  A space will be

>           appended after the last substition unless there is more

>           text in current sequence.

> 

> this ought to mean that every -mcpu= option results in a corresponding cpu 

> <something> in the arguments to canon_arch (in the same order as the 

> original options).  If it doesn't, that sounds like a bug in the %* 

> handling.

> 


So when I investigated this further this afternoon I made the following
observations.

Firstly, sometimes all the -march options were being passed through and
sometimes only the first.  That seemed odd, so I dug a bit further.  It
seems the later options are cancelled by the %<march=* component of

	%{march=*: arch %* %<march=*}.

But only sometimes...  It seems that the gating criteria for whether or
not they are cancelled is that if -marm is on the command line the
second and subsequent options are cancelled; if it isn't (and I'm
guessing, if -mthumb is also not present) then the subsequent -march
options are passed through.

Now why would that make a difference?  After all, -marm/-mthumb isn't
used at all in this rule.  At this stage I can only speculate that
%{march=*: arch %*} is also used by the the TARGET_MODE_SPEC_FUNCTION
rule and that this is somehow causing the array to be cached?

I need to do some more digging here, but it seems that at the very least
the behaviour is not consistent.  Whether or not this rule should be
supportable or not is still TBD.

In fact I probably don't need the %<march=* part of the rule.  I hadn't
realized that is was possible to maintain all such options and just
interpret the last one.  So for my purposes that might be the best
solution, since my canon_arch generated option will simply override any
existing -march options.

> Overridden options can be removed before specs processing if a cycle of 

> options is marked with Negative in the .opt files (see prune_options), but 

> that doesn't apply to options with arguments.  If you had a system for 

> pruning e.g. all but the last -mcpu= option (for options where it's just 

> the last argument that matters), you'd also want to make sure that prior 

> options do still generate errors if the option argument is invalid.

> 


R.
Richard Earnshaw (lists) June 13, 2017, 9:40 a.m. UTC | #8
On 12/06/17 22:27, Richard Earnshaw (lists) wrote:
> In fact I probably don't need the %<march=* part of the rule.  I hadn't

> realized that is was possible to maintain all such options and just

> interpret the last one.  So for my purposes that might be the best

> solution, since my canon_arch generated option will simply override any

> existing -march options.


It turns out this won't work.  The multilib selection machinery looks at
all the -march= options to make its decision and it is completely
unaware of the fact that only the last one is relevant.

This was broken before my changes, but the consequences are more severe now.

I wonder if we should/could add a LAST attribute to the options
specification such that the driver discards all but the final instance
of such an option.  This would also solve the -mcpu=native problem since
the discard rule would kick in and eliminate that option if it wasn't
the final one in the list.

We clearly can't apply that to every option, since for example -ffixed=
needs to accumulate, as do options such as -I; but others are clearly
overrides.

R.
Joseph Myers June 13, 2017, 10:29 a.m. UTC | #9
On Tue, 13 Jun 2017, Richard Earnshaw (lists) wrote:

> I wonder if we should/could add a LAST attribute to the options

> specification such that the driver discards all but the final instance

> of such an option.  This would also solve the -mcpu=native problem since

> the discard rule would kick in and eliminate that option if it wasn't

> the final one in the list.


As noted, I think all the options should be validated before discarding in 
such a case (which is easy for Enum options, but for options with custom 
parsing code care would need to be taken that this code is run for 
validation purposes before discarding).

-- 
Joseph S. Myers
joseph@codesourcery.com
Richard Earnshaw (lists) June 13, 2017, 3:25 p.m. UTC | #10
On 12/06/17 15:34, Richard Earnshaw (lists) wrote:
> On 12/06/17 12:49, Christophe Lyon wrote:

>> On 10 June 2017 at 01:27, Richard Earnshaw (lists)

>> <Richard.Earnshaw@arm.com> wrote:

>>> On 09/06/17 23:45, Christophe Lyon wrote:

>>>> Hi Richard,

>>>>

>>>>

>>>> On 9 June 2017 at 14:53, Richard Earnshaw <Richard.Earnshaw@arm.com> wrote:

>>>>>

>>>>> During the ARM BoF at the Cauldron last year I mentioned that I wanted

>>>>> to rework the way GCC on ARM handles the command line options.  The

>>>>> problem was that most users, and even many experts, can't remember

>>>>> which FPU/SIMD unit comes with which CPU and that consequently many

>>>>> users were inadvertenly generating sub-optimal code for their system.

>>>>>

>>>>> This patch series implements the proposed change and provides support

>>>>> for a generic way of adding optional features to architectures and CPU

>>>>> names.  The documentation patches at the end of the series explain the

>>>>> new syntax, so I won't repeat all that here.  Suffice to say here that

>>>>> the result is that the -mfpu option now defaults to 'auto', which

>>>>> allows the compiler to infer the floating-point and simd options from

>>>>> the CPU/architecture options and that these options can normally be

>>>>> expressed in a context-specific manner like +simd or +fp without

>>>>> having to know precisely which variant is implemented.  Long term I'd

>>>>> like to deprecate -mfpu and entirely move over to the new syntax; but

>>>>> it's too early to start that process now.

>>>>>

>>>>> All the patches in the series should build a working basic compiler,

>>>>> but the multilib selection will not work correctly until the relevant

>>>>> patches towards the end are applied.  It is not really feasible to

>>>>> retain that functionality without collapsing too many of the patches

>>>>> together into one hunk.  It's also possible that some tests in the

>>>>> testsuite may exhibit transient misbehaviour, but there should be no

>>>>> regressions by the end of the sequence (some tests no-longer run in

>>>>> the default configurations because the default CPU does not have

>>>>> floating-point support).

>>>>>

>>>>> Just two patches are to the generic code, but both are fairly trivial.

>>>>> One permits the sbitmap code to be used in the driver programs and the

>>>>> other provides a way of escaping the meta-character in some multilib

>>>>> reuse strings.

>>>>>

>>>>> I won't apply any of this series until those two patches have been

>>>>> approved, and I won't commit anything before the middle of next week

>>>>> even then.  This is a fairly complex change and it deserves some time

>>>>> for people to comment before committing.

>>>>>

>>>>> R.

>>>>>

>>>>> Richard Earnshaw (30):

>>>>>   [arm] Use strings for -march, -mcpu and -mtune options

>>>>>   [arm] Rewrite -march and -mcpu options for passing to the assembler

>>>>>   [arm] Don't pass -mfpu=auto through to the assembler.

>>>>>   [arm] Allow +opt on arbitrary cpu and architecture specifications

>>>>>   [arm] Add architectural options

>>>>>   [arm] Add default FPUs for CPUs.

>>>>>   [build] Make sbitmap code available to the driver programs

>>>>>   [arm] Split CPU, architecture and tuning data tables.

>>>>>   [ARM] Move cpu and architecture option name parsing code to

>>>>>     arm-common.c

>>>>>   [arm] Use standard option parsing code for detecting thumb-only

>>>>>     targets

>>>>>   [arm] Allow CPU and architecture extensions to be defined as aliases

>>>>>   [arm] Allow new extended syntax CPU and architecture names during

>>>>>     configure

>>>>>   [arm] Force a CPU default in the config args defaults list.

>>>>>   [arm] Generate a canonical form for -march

>>>>>   [arm] Make -mfloat-abi=softfp work when there are no FPU instructions

>>>>>   [arm] Update basic multilib configuration

>>>>>   [arm] Make 'auto' the default FPU selection option.

>>>>>   [arm] Rewrite t-aprofile using new selector methodology

>>>>>   [arm] Explicitly set .fpu in cmse_nonsecure_call.S

>>>>>   [genmultilib] Allow explicit periods to be escaped in MULTILIB_REUSE

>>>>>   [arm][testsuite] Use -march=armv7-a+fp when testing hard-float ABI.

>>>>>   [arm] Rewrite t-rmprofile multilib specification

>>>>>   [arm][rtems] Update t-rtems for new option framework

>>>>>   [arm][linux-eabi] Ensure all multilib variables are reset

>>>>>   [arm][phoenix] reset all multilib variables

>>>>>   [arm] Rework multlib builds for symbianelf

>>>>>   [arm][fuchsia] Rework multilib support

>>>>>   [arm] Add a few missing architecture extension options.

>>>>>   [arm][doc] Document new -march= syntax.

>>>>>   [arm][doc] Document changes to -mcpu, -mtune and -mfpu.

>>>>>

>>>>>  gcc/Makefile.in                           |    2 +-

>>>>>  gcc/common/config/arm/arm-common.c        |  651 +++++++-

>>>>>  gcc/config.gcc                            |   17 +-

>>>>>  gcc/config/arm/arm-builtins.c             |    4 +-

>>>>>  gcc/config/arm/arm-cpu-cdata.h            | 2444 +++++++++++++++++++++++------

>>>>>  gcc/config/arm/arm-cpu-data.h             | 1410 ++---------------

>>>>>  gcc/config/arm/arm-cpu.h                  |   38 +

>>>>>  gcc/config/arm/arm-cpus.in                |  237 ++-

>>>>>  gcc/config/arm/arm-isa.h                  |   20 +-

>>>>>  gcc/config/arm/arm-protos.h               |   56 +-

>>>>>  gcc/config/arm/arm-tables.opt             |   21 +-

>>>>>  gcc/config/arm/arm.c                      |  337 ++--

>>>>>  gcc/config/arm/arm.h                      |   75 +-

>>>>>  gcc/config/arm/arm.opt                    |   15 +-

>>>>>  gcc/config/arm/bpabi.h                    |    4 -

>>>>>  gcc/config/arm/elf.h                      |    6 +-

>>>>>  gcc/config/arm/linux-elf.h                |    3 -

>>>>>  gcc/config/arm/netbsd-elf.h               |    4 -

>>>>>  gcc/config/arm/parsecpu.awk               |  295 +++-

>>>>>  gcc/config/arm/t-aprofile                 |  200 +--

>>>>>  gcc/config/arm/t-arm-elf                  |  173 +-

>>>>>  gcc/config/arm/t-fuchsia                  |   33 +

>>>>>  gcc/config/arm/t-linux-eabi               |    4 +

>>>>>  gcc/config/arm/t-multilib                 |  126 +-

>>>>>  gcc/config/arm/t-phoenix                  |   20 +-

>>>>>  gcc/config/arm/t-rmprofile                |  147 +-

>>>>>  gcc/config/arm/t-rtems                    |   49 +-

>>>>>  gcc/config/arm/t-symbian                  |   34 +-

>>>>>  gcc/config/arm/vxworks.h                  |    2 -

>>>>>  gcc/doc/fragments.texi                    |   10 +-

>>>>>  gcc/doc/invoke.texi                       |  371 ++++-

>>>>>  gcc/genmultilib                           |    4 +-

>>>>>  gcc/testsuite/gcc.dg/pr59418.c            |    2 +-

>>>>>  gcc/testsuite/gcc.target/arm/multilib.exp |  685 ++++++++

>>>>>  gcc/testsuite/gcc.target/arm/pr51915.c    |    2 +-

>>>>>  gcc/testsuite/gcc.target/arm/pr52006.c    |    2 +-

>>>>>  gcc/testsuite/gcc.target/arm/pr53187.c    |    2 +-

>>>>>  libgcc/config/arm/cmse_nonsecure_call.S   |    8 +

>>>>>  38 files changed, 5073 insertions(+), 2440 deletions(-)

>>>>>  create mode 100644 gcc/config/arm/t-fuchsia

>>>>>  create mode 100644 gcc/testsuite/gcc.target/arm/multilib.exp

>>>>>

>>>>> ----------------2.7.4--

>>>>>

>>>>

>>>> I wanted to run a validation with the full series applied as one patch

>>>> over r249050,

>>>> so I just downloaded all the patches, concatenated them in order, but the result

>>>> fails to apply. (conflicts with arm-cpu-cdata.h, arm-cpus.in,

>>>> t-aprofile, t-rmprofile)

>>>>

>>>> Am I missing something?

>>>>

>>>> Thanks,

>>>>

>>>> Christophe

>>>>

>>>

>>> I really appreciate you trying to do this...

>>>

>>> I rebased the patch series sometime on Tuesday/Wednesday just before Jim

>>> Wilson committed his falkor change; you'll need to back out to just

>>> before r248944.  I can't think of anything else that might have just

>>> gone in that might conflict.  For arm-cpu-cdata.h (and the other

>>> auto-generated files, like arm-cpu-data.h) you can just delete the file

>>> and it will be rebuilt automatically, the others really do need the

>>> conflict to be resolved.

>>>

>>> Obviously I'll rebase again just before the commit, but propagating such

>>> changes through the patch series is quite tedious and I don't want to do

>>> it any more than necessary :-).

>>>

>>> It would be easier if the generated files weren't checked in to the

>>> repository...

>>>

>>> R.

>>

>> Hi Richard,

>>

>> Starting a validation of the whole patch against r248942 did work, thanks.

>>

>> The results are here:

>> http://people.linaro.org/~christophe.lyon/cross-validation/gcc-test-patches/248942-rework-cpu-arch-fpu.patch/report-build-info.html

>>

>> Regressions are detected in many configurations, unfortunately.

>> Some may be caused by the fact that I've upgraded to dejagnu-1.6+ for

>> my testing,

>> and thus "multilib flags" are now prepended rather than appended, but

>> I don't think that's the majority.

>>

>> To help you understand/group all the reports:

>> - all "arm-none-linux-gnueabi" with REGRESSED now have:

>> FAIL: gcc.target/arm/neon-thumb2-move.c (test for excess errors)

> 

> See later.

> 

>> FAIL: gcc.target/arm/no-volatile-in-it.c scan-assembler-not ldrgt

>> - same for the 2 configs arm-none-eabi --with-cpu=cortex-a9

> 

> I'm checking a fix for this, I think I understand what's going on here.

> 

>>

>> - all "arm-none-linux-gnueabihf" and "armeb-none-linux-gnueabihf" with

>> REGRESSED now have:

>> FAIL: gcc.target/arm/no-volatile-in-it.c scan-assembler-not ldrgt

>>

>> - arm-none-eabi --with-cpu=cortex-m3 now has:

>> FAIL:

>>     gcc.target/arm/no-volatile-in-it.c scan-assembler-not ldrgt

>>     gcc.target/arm/thumb2-slow-flash-data-2.c (test for excess errors)

>>     gcc.target/arm/thumb2-slow-flash-data-3.c (test for excess errors)

>>     gcc.target/arm/thumb2-slow-flash-data-4.c (test for excess errors)

>>     gcc.target/arm/thumb2-slow-flash-data-5.c (test for excess errors)

>> UNRESOLVED:

>>     gcc.target/arm/thumb2-slow-flash-data-4.c scan-assembler-times #1\\.0e\\+0 3

>>     gcc.target/arm/thumb2-slow-flash-data-5.c scan-assembler-not #1\\.0e\\+0

>>

>> - The 2 cells with "BIG-REG" mean regressions where detected, but the report

>> is >100kb so it was attached as a .xz file, click on 'BIG-REG" to download it.

>>

>> - the cells with "BETTER" can be questionable: it means no new failure

>> appeared, but PASS -> UNSUPPORTED is considered as "better". Here

>> we have cases with several thousands (!) of tests becoming unsupported,

>> which looks a bit suspicious.

>>

>> Among other things, I've noticed that when passing -march=armv5t,

>> arm_neon_ok fails:

>> xgcc -march=armv5t -fno-diagnostics-show-caret

>> -fdiagnostics-color=never -mfpu=neon -mfloat-abi=softfp -march=

>> armv7-a -c -o arm_neon_ok15574.o arm_neon_ok15574.c

>> arm_neon_ok15574.c:9:4: error: #error Architecture does not support NEON.

>> compiler exited with status 1

>>

>> I'd expect -march=armv7-a to allow to use -mfpu=neon?

>>

> 

> It does.  The problem seems to be a generic one in the driver in that

> the rewrite rules are always passed the first instance of -march and not

> the last.  Indeed, with the aarch64 compiler, if I write

> 

> gcc -mcpu=native -mcpu=cortex-a53

> 

> then the driver will rewrite this as

> 

> ./cc1 -mcpu=cortex-a53 -mcpu=<expansion of native cpu name>

> 

> which doesn't seem to be the right thing at all.

> 

> So we either have a generic problem with all option rewriting, or there

> are some subtle details of it that we've not figured out yet.

> 


It turns out that there's also a problem with the test framework for
this particular test.

The test has:

/* { dg-require-effective-target arm_neon_ok } */
/* { dg-require-effective-target arm_thumb2_ok } */
/* { dg-options "-O2 -mthumb -march=armv7-a" } */
/* { dg-add-options arm_neon } */

This combination of flags goes through the following process:

firstly it checks that Neon is ok.  That's fine
Then it checks for thumb2.  That's also fine
Then it adds the extra options.
Finally it adds any final options needed to enable Neon.

Unfortunately, the last step uses a cache.  The cache is based on trying
a number of options from the default option set, which inherits from the
options built into the compiler, which in this case is -mcpu=cortex-a9.

Now since -mcpu=cortex-a9 now implies neon, the generic framework
deduces (correctly) that -mfloat-abi=softfp is sufficient to enable neon.

Unfortunately, this is the point at which the dg-options statement
messes things up - the -march=armv7-a overrides the internally selected
default CPU (cortex-a9) and thus removes Neon (simd) from the
instruction set, since we haven't specified an architecture that
supports SIMD.

I think the correct (second) fix for this test is to remove the -march
option entirely from the dg-options list and then rely on dg-add-options
arm_neon adding the correct flags for this target configuration.

R.
Christophe Lyon June 13, 2017, 4:08 p.m. UTC | #11
On 13 June 2017 at 17:25, Richard Earnshaw (lists)
<Richard.Earnshaw@arm.com> wrote:
> On 12/06/17 15:34, Richard Earnshaw (lists) wrote:

>> On 12/06/17 12:49, Christophe Lyon wrote:

>>> On 10 June 2017 at 01:27, Richard Earnshaw (lists)

>>> <Richard.Earnshaw@arm.com> wrote:

>>>> On 09/06/17 23:45, Christophe Lyon wrote:

>>>>> Hi Richard,

>>>>>

>>>>>

>>>>> On 9 June 2017 at 14:53, Richard Earnshaw <Richard.Earnshaw@arm.com> wrote:

>>>>>>

>>>>>> During the ARM BoF at the Cauldron last year I mentioned that I wanted

>>>>>> to rework the way GCC on ARM handles the command line options.  The

>>>>>> problem was that most users, and even many experts, can't remember

>>>>>> which FPU/SIMD unit comes with which CPU and that consequently many

>>>>>> users were inadvertenly generating sub-optimal code for their system.

>>>>>>

>>>>>> This patch series implements the proposed change and provides support

>>>>>> for a generic way of adding optional features to architectures and CPU

>>>>>> names.  The documentation patches at the end of the series explain the

>>>>>> new syntax, so I won't repeat all that here.  Suffice to say here that

>>>>>> the result is that the -mfpu option now defaults to 'auto', which

>>>>>> allows the compiler to infer the floating-point and simd options from

>>>>>> the CPU/architecture options and that these options can normally be

>>>>>> expressed in a context-specific manner like +simd or +fp without

>>>>>> having to know precisely which variant is implemented.  Long term I'd

>>>>>> like to deprecate -mfpu and entirely move over to the new syntax; but

>>>>>> it's too early to start that process now.

>>>>>>

>>>>>> All the patches in the series should build a working basic compiler,

>>>>>> but the multilib selection will not work correctly until the relevant

>>>>>> patches towards the end are applied.  It is not really feasible to

>>>>>> retain that functionality without collapsing too many of the patches

>>>>>> together into one hunk.  It's also possible that some tests in the

>>>>>> testsuite may exhibit transient misbehaviour, but there should be no

>>>>>> regressions by the end of the sequence (some tests no-longer run in

>>>>>> the default configurations because the default CPU does not have

>>>>>> floating-point support).

>>>>>>

>>>>>> Just two patches are to the generic code, but both are fairly trivial.

>>>>>> One permits the sbitmap code to be used in the driver programs and the

>>>>>> other provides a way of escaping the meta-character in some multilib

>>>>>> reuse strings.

>>>>>>

>>>>>> I won't apply any of this series until those two patches have been

>>>>>> approved, and I won't commit anything before the middle of next week

>>>>>> even then.  This is a fairly complex change and it deserves some time

>>>>>> for people to comment before committing.

>>>>>>

>>>>>> R.

>>>>>>

>>>>>> Richard Earnshaw (30):

>>>>>>   [arm] Use strings for -march, -mcpu and -mtune options

>>>>>>   [arm] Rewrite -march and -mcpu options for passing to the assembler

>>>>>>   [arm] Don't pass -mfpu=auto through to the assembler.

>>>>>>   [arm] Allow +opt on arbitrary cpu and architecture specifications

>>>>>>   [arm] Add architectural options

>>>>>>   [arm] Add default FPUs for CPUs.

>>>>>>   [build] Make sbitmap code available to the driver programs

>>>>>>   [arm] Split CPU, architecture and tuning data tables.

>>>>>>   [ARM] Move cpu and architecture option name parsing code to

>>>>>>     arm-common.c

>>>>>>   [arm] Use standard option parsing code for detecting thumb-only

>>>>>>     targets

>>>>>>   [arm] Allow CPU and architecture extensions to be defined as aliases

>>>>>>   [arm] Allow new extended syntax CPU and architecture names during

>>>>>>     configure

>>>>>>   [arm] Force a CPU default in the config args defaults list.

>>>>>>   [arm] Generate a canonical form for -march

>>>>>>   [arm] Make -mfloat-abi=softfp work when there are no FPU instructions

>>>>>>   [arm] Update basic multilib configuration

>>>>>>   [arm] Make 'auto' the default FPU selection option.

>>>>>>   [arm] Rewrite t-aprofile using new selector methodology

>>>>>>   [arm] Explicitly set .fpu in cmse_nonsecure_call.S

>>>>>>   [genmultilib] Allow explicit periods to be escaped in MULTILIB_REUSE

>>>>>>   [arm][testsuite] Use -march=armv7-a+fp when testing hard-float ABI.

>>>>>>   [arm] Rewrite t-rmprofile multilib specification

>>>>>>   [arm][rtems] Update t-rtems for new option framework

>>>>>>   [arm][linux-eabi] Ensure all multilib variables are reset

>>>>>>   [arm][phoenix] reset all multilib variables

>>>>>>   [arm] Rework multlib builds for symbianelf

>>>>>>   [arm][fuchsia] Rework multilib support

>>>>>>   [arm] Add a few missing architecture extension options.

>>>>>>   [arm][doc] Document new -march= syntax.

>>>>>>   [arm][doc] Document changes to -mcpu, -mtune and -mfpu.

>>>>>>

>>>>>>  gcc/Makefile.in                           |    2 +-

>>>>>>  gcc/common/config/arm/arm-common.c        |  651 +++++++-

>>>>>>  gcc/config.gcc                            |   17 +-

>>>>>>  gcc/config/arm/arm-builtins.c             |    4 +-

>>>>>>  gcc/config/arm/arm-cpu-cdata.h            | 2444 +++++++++++++++++++++++------

>>>>>>  gcc/config/arm/arm-cpu-data.h             | 1410 ++---------------

>>>>>>  gcc/config/arm/arm-cpu.h                  |   38 +

>>>>>>  gcc/config/arm/arm-cpus.in                |  237 ++-

>>>>>>  gcc/config/arm/arm-isa.h                  |   20 +-

>>>>>>  gcc/config/arm/arm-protos.h               |   56 +-

>>>>>>  gcc/config/arm/arm-tables.opt             |   21 +-

>>>>>>  gcc/config/arm/arm.c                      |  337 ++--

>>>>>>  gcc/config/arm/arm.h                      |   75 +-

>>>>>>  gcc/config/arm/arm.opt                    |   15 +-

>>>>>>  gcc/config/arm/bpabi.h                    |    4 -

>>>>>>  gcc/config/arm/elf.h                      |    6 +-

>>>>>>  gcc/config/arm/linux-elf.h                |    3 -

>>>>>>  gcc/config/arm/netbsd-elf.h               |    4 -

>>>>>>  gcc/config/arm/parsecpu.awk               |  295 +++-

>>>>>>  gcc/config/arm/t-aprofile                 |  200 +--

>>>>>>  gcc/config/arm/t-arm-elf                  |  173 +-

>>>>>>  gcc/config/arm/t-fuchsia                  |   33 +

>>>>>>  gcc/config/arm/t-linux-eabi               |    4 +

>>>>>>  gcc/config/arm/t-multilib                 |  126 +-

>>>>>>  gcc/config/arm/t-phoenix                  |   20 +-

>>>>>>  gcc/config/arm/t-rmprofile                |  147 +-

>>>>>>  gcc/config/arm/t-rtems                    |   49 +-

>>>>>>  gcc/config/arm/t-symbian                  |   34 +-

>>>>>>  gcc/config/arm/vxworks.h                  |    2 -

>>>>>>  gcc/doc/fragments.texi                    |   10 +-

>>>>>>  gcc/doc/invoke.texi                       |  371 ++++-

>>>>>>  gcc/genmultilib                           |    4 +-

>>>>>>  gcc/testsuite/gcc.dg/pr59418.c            |    2 +-

>>>>>>  gcc/testsuite/gcc.target/arm/multilib.exp |  685 ++++++++

>>>>>>  gcc/testsuite/gcc.target/arm/pr51915.c    |    2 +-

>>>>>>  gcc/testsuite/gcc.target/arm/pr52006.c    |    2 +-

>>>>>>  gcc/testsuite/gcc.target/arm/pr53187.c    |    2 +-

>>>>>>  libgcc/config/arm/cmse_nonsecure_call.S   |    8 +

>>>>>>  38 files changed, 5073 insertions(+), 2440 deletions(-)

>>>>>>  create mode 100644 gcc/config/arm/t-fuchsia

>>>>>>  create mode 100644 gcc/testsuite/gcc.target/arm/multilib.exp

>>>>>>

>>>>>> ----------------2.7.4--

>>>>>>

>>>>>

>>>>> I wanted to run a validation with the full series applied as one patch

>>>>> over r249050,

>>>>> so I just downloaded all the patches, concatenated them in order, but the result

>>>>> fails to apply. (conflicts with arm-cpu-cdata.h, arm-cpus.in,

>>>>> t-aprofile, t-rmprofile)

>>>>>

>>>>> Am I missing something?

>>>>>

>>>>> Thanks,

>>>>>

>>>>> Christophe

>>>>>

>>>>

>>>> I really appreciate you trying to do this...

>>>>

>>>> I rebased the patch series sometime on Tuesday/Wednesday just before Jim

>>>> Wilson committed his falkor change; you'll need to back out to just

>>>> before r248944.  I can't think of anything else that might have just

>>>> gone in that might conflict.  For arm-cpu-cdata.h (and the other

>>>> auto-generated files, like arm-cpu-data.h) you can just delete the file

>>>> and it will be rebuilt automatically, the others really do need the

>>>> conflict to be resolved.

>>>>

>>>> Obviously I'll rebase again just before the commit, but propagating such

>>>> changes through the patch series is quite tedious and I don't want to do

>>>> it any more than necessary :-).

>>>>

>>>> It would be easier if the generated files weren't checked in to the

>>>> repository...

>>>>

>>>> R.

>>>

>>> Hi Richard,

>>>

>>> Starting a validation of the whole patch against r248942 did work, thanks.

>>>

>>> The results are here:

>>> http://people.linaro.org/~christophe.lyon/cross-validation/gcc-test-patches/248942-rework-cpu-arch-fpu.patch/report-build-info.html

>>>

>>> Regressions are detected in many configurations, unfortunately.

>>> Some may be caused by the fact that I've upgraded to dejagnu-1.6+ for

>>> my testing,

>>> and thus "multilib flags" are now prepended rather than appended, but

>>> I don't think that's the majority.

>>>

>>> To help you understand/group all the reports:

>>> - all "arm-none-linux-gnueabi" with REGRESSED now have:

>>> FAIL: gcc.target/arm/neon-thumb2-move.c (test for excess errors)

>>

>> See later.

>>

>>> FAIL: gcc.target/arm/no-volatile-in-it.c scan-assembler-not ldrgt

>>> - same for the 2 configs arm-none-eabi --with-cpu=cortex-a9

>>

>> I'm checking a fix for this, I think I understand what's going on here.

>>

>>>

>>> - all "arm-none-linux-gnueabihf" and "armeb-none-linux-gnueabihf" with

>>> REGRESSED now have:

>>> FAIL: gcc.target/arm/no-volatile-in-it.c scan-assembler-not ldrgt

>>>

>>> - arm-none-eabi --with-cpu=cortex-m3 now has:

>>> FAIL:

>>>     gcc.target/arm/no-volatile-in-it.c scan-assembler-not ldrgt

>>>     gcc.target/arm/thumb2-slow-flash-data-2.c (test for excess errors)

>>>     gcc.target/arm/thumb2-slow-flash-data-3.c (test for excess errors)

>>>     gcc.target/arm/thumb2-slow-flash-data-4.c (test for excess errors)

>>>     gcc.target/arm/thumb2-slow-flash-data-5.c (test for excess errors)

>>> UNRESOLVED:

>>>     gcc.target/arm/thumb2-slow-flash-data-4.c scan-assembler-times #1\\.0e\\+0 3

>>>     gcc.target/arm/thumb2-slow-flash-data-5.c scan-assembler-not #1\\.0e\\+0

>>>

>>> - The 2 cells with "BIG-REG" mean regressions where detected, but the report

>>> is >100kb so it was attached as a .xz file, click on 'BIG-REG" to download it.

>>>

>>> - the cells with "BETTER" can be questionable: it means no new failure

>>> appeared, but PASS -> UNSUPPORTED is considered as "better". Here

>>> we have cases with several thousands (!) of tests becoming unsupported,

>>> which looks a bit suspicious.

>>>

>>> Among other things, I've noticed that when passing -march=armv5t,

>>> arm_neon_ok fails:

>>> xgcc -march=armv5t -fno-diagnostics-show-caret

>>> -fdiagnostics-color=never -mfpu=neon -mfloat-abi=softfp -march=

>>> armv7-a -c -o arm_neon_ok15574.o arm_neon_ok15574.c

>>> arm_neon_ok15574.c:9:4: error: #error Architecture does not support NEON.

>>> compiler exited with status 1

>>>

>>> I'd expect -march=armv7-a to allow to use -mfpu=neon?

>>>

>>

>> It does.  The problem seems to be a generic one in the driver in that

>> the rewrite rules are always passed the first instance of -march and not

>> the last.  Indeed, with the aarch64 compiler, if I write

>>

>> gcc -mcpu=native -mcpu=cortex-a53

>>

>> then the driver will rewrite this as

>>

>> ./cc1 -mcpu=cortex-a53 -mcpu=<expansion of native cpu name>

>>

>> which doesn't seem to be the right thing at all.

>>

>> So we either have a generic problem with all option rewriting, or there

>> are some subtle details of it that we've not figured out yet.

>>

>

> It turns out that there's also a problem with the test framework for

> this particular test.

>

I'm not sure which particular test you are referring to?

> The test has:

>

> /* { dg-require-effective-target arm_neon_ok } */

> /* { dg-require-effective-target arm_thumb2_ok } */

> /* { dg-options "-O2 -mthumb -march=armv7-a" } */

> /* { dg-add-options arm_neon } */

>

> This combination of flags goes through the following process:

>

> firstly it checks that Neon is ok.  That's fine

> Then it checks for thumb2.  That's also fine

> Then it adds the extra options.

> Finally it adds any final options needed to enable Neon.

>

> Unfortunately, the last step uses a cache.  The cache is based on trying

> a number of options from the default option set, which inherits from the

> options built into the compiler, which in this case is -mcpu=cortex-a9.

>

> Now since -mcpu=cortex-a9 now implies neon, the generic framework

> deduces (correctly) that -mfloat-abi=softfp is sufficient to enable neon.

>

> Unfortunately, this is the point at which the dg-options statement

> messes things up - the -march=armv7-a overrides the internally selected

> default CPU (cortex-a9) and thus removes Neon (simd) from the

> instruction set, since we haven't specified an architecture that

> supports SIMD.

>

> I think the correct (second) fix for this test is to remove the -march

> option entirely from the dg-options list and then rely on dg-add-options

> arm_neon adding the correct flags for this target configuration.

>


Indeed, I think in general there should be no such -march=XXX option
in dg-options and that should be handled by the
dg-require-effective-target/dg-add-options pair.
Why was -march=armv7-a added to this test in the first place?

> R.

>
Richard Earnshaw (lists) June 13, 2017, 5:27 p.m. UTC | #12
-marm and -mthumb are opposites: one cancels out the other.  This patch
marks them as such so that the driver will eliminate all but the last
option on the command line.  This aids multilib selection which
otherwise can get confused if both are present.

	* config/arm/arm.opt (marm): Mark as the negative of of -mthumb.
	(mthumb): Mark as the negative of -marm.


R.diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index efee1be..dad5257 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -91,7 +91,7 @@ EnumValue
 Enum(arm_arch) String(native) Value(-1) DriverOnly
 
 marm
-Target Report RejectNegative InverseMask(THUMB)
+Target Report RejectNegative Negative(mthumb) InverseMask(THUMB)
 Generate code in 32 bit ARM state.
 
 mbig-endian
@@ -195,7 +195,7 @@ Target RejectNegative Joined UInteger Var(arm_structure_size_boundary) Init(DEFA
 Specify the minimum bit alignment of structures.
 
 mthumb
-Target Report RejectNegative Mask(THUMB) Save
+Target Report RejectNegative Negative(marm) Mask(THUMB) Save
 Generate code for Thumb state.
 
 mthumb-interwork

Richard Earnshaw (lists) June 13, 2017, 5:29 p.m. UTC | #13
This test was overriding the options that had been detected as being
necessary to enable Neon.  The result was that the combination of the
test's options and those auto-detected were not compatible with neon
leading to a test failure.  The correct fix here is to stick with the
options that dg-add-options arm_neon has worked out.

	* gcc.target/arm/neon-thumb2-move.c (dg-options): Don't override
	the architecture options added by dg-add-options arm_neon.diff --git a/gcc/testsuite/gcc.target/arm/neon-thumb2-move.c b/gcc/testsuite/gcc.target/arm/neon-thumb2-move.c
index 9cf86dd..d8c6748 100644
--- a/gcc/testsuite/gcc.target/arm/neon-thumb2-move.c
+++ b/gcc/testsuite/gcc.target/arm/neon-thumb2-move.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target arm_neon_ok } */
 /* { dg-require-effective-target arm_thumb2_ok } */
-/* { dg-options "-O2 -mthumb -march=armv7-a" } */
+/* { dg-options "-O2 -mthumb" } */
 /* { dg-add-options arm_neon } */
 /* { dg-prune-output "switch .* conflicts with" } */
 

Richard Earnshaw (lists) June 13, 2017, 5:35 p.m. UTC | #14
On 09/06/17 13:53, Richard Earnshaw wrote:
> 

> During the ARM BoF at the Cauldron last year I mentioned that I wanted

> to rework the way GCC on ARM handles the command line options.  The

> problem was that most users, and even many experts, can't remember

> which FPU/SIMD unit comes with which CPU and that consequently many

> users were inadvertenly generating sub-optimal code for their system.

> 

> This patch series implements the proposed change and provides support

> for a generic way of adding optional features to architectures and CPU

> names.  The documentation patches at the end of the series explain the

> new syntax, so I won't repeat all that here.  Suffice to say here that

> the result is that the -mfpu option now defaults to 'auto', which

> allows the compiler to infer the floating-point and simd options from

> the CPU/architecture options and that these options can normally be

> expressed in a context-specific manner like +simd or +fp without

> having to know precisely which variant is implemented.  Long term I'd

> like to deprecate -mfpu and entirely move over to the new syntax; but

> it's too early to start that process now.

> 

> All the patches in the series should build a working basic compiler,

> but the multilib selection will not work correctly until the relevant

> patches towards the end are applied.  It is not really feasible to

> retain that functionality without collapsing too many of the patches

> together into one hunk.  It's also possible that some tests in the

> testsuite may exhibit transient misbehaviour, but there should be no

> regressions by the end of the sequence (some tests no-longer run in

> the default configurations because the default CPU does not have

> floating-point support).

> 

> Just two patches are to the generic code, but both are fairly trivial.

> One permits the sbitmap code to be used in the driver programs and the

> other provides a way of escaping the meta-character in some multilib

> reuse strings.

> 

> I won't apply any of this series until those two patches have been

> approved, and I won't commit anything before the middle of next week

> even then.  This is a fairly complex change and it deserves some time

> for people to comment before committing.

> 


The attached is a roll-up of the entire series after the updates I've
posted today.  This should eliminate any potential issues with applying
the series for the purposes of testing.  Please don't post issues in
reply to this, but to the individual patches in the series.

R.diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index da98c8e..67d69c1 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1441,7 +1441,6 @@ OBJS = \
 	rtlanal.o \
 	rtlhooks.o \
 	run-rtl-passes.o \
-	sbitmap.o \
 	sched-deps.o \
 	sched-ebb.o \
 	sched-rgn.o \
@@ -1587,6 +1586,7 @@ OBJS = \
 OBJS-libcommon = diagnostic.o diagnostic-color.o diagnostic-show-locus.o \
 	edit-context.o \
 	pretty-print.o intl.o \
+	sbitmap.o \
 	vec.o input.o version.o hash-table.o ggc-none.o memory-block.o \
 	selftest.o
 
diff --git a/gcc/common/config/arm/arm-common.c b/gcc/common/config/arm/arm-common.c
index 7ecc68d..d06c39b 100644
--- a/gcc/common/config/arm/arm-common.c
+++ b/gcc/common/config/arm/arm-common.c
@@ -17,6 +17,7 @@
    along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
+#define INCLUDE_LIST
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
@@ -27,6 +28,8 @@
 #include "common/common-target-def.h"
 #include "opts.h"
 #include "flags.h"
+#include "sbitmap.h"
+#include "diagnostic.h"
 
 /* Set default optimization options.  */
 static const struct default_options arm_option_optimization_table[] =
@@ -66,7 +69,7 @@ arm_except_unwind_info (struct gcc_options *opts)
 
 #define ARM_CPU_NAME_LENGTH 20
 
-/* Truncate NAME at the first '.' character seen, or return
+/* Truncate NAME at the first '.' or '+' character seen, or return
    NAME unmodified.  */
 
 const char *
@@ -76,12 +79,20 @@ arm_rewrite_selected_cpu (const char *name)
   char *arg_pos;
 
   strncpy (output_buf, name, ARM_CPU_NAME_LENGTH);
+  output_buf[ARM_CPU_NAME_LENGTH] = 0;
+
   arg_pos = strchr (output_buf, '.');
 
   /* If we found a '.' truncate the entry at that point.  */
   if (arg_pos)
     *arg_pos = '\0';
 
+  arg_pos = strchr (output_buf, '+');
+
+  /* If we found a '+' truncate the entry at that point.  */
+  if (arg_pos)
+    *arg_pos = '\0';
+
   return output_buf;
 }
 
@@ -98,11 +109,40 @@ arm_rewrite_mcpu (int argc, const char **argv)
   return arm_rewrite_selected_cpu (argv[argc - 1]);
 }
 
-struct arm_arch_core_flag
+/* Truncate NAME at the first '+' character seen, or return
+   NAME unmodified.  Similar to arm_rewrite_selected_cpu, but we must
+   preserve '.' as that is part of some architecture names.  */
+
+const char *
+arm_rewrite_selected_arch (const char *name)
 {
-  const char *const name;
-  const enum isa_feature isa_bits[isa_num_bits];
-};
+  static char output_buf[ARM_CPU_NAME_LENGTH + 1] = {0};
+  char *arg_pos;
+
+  strncpy (output_buf, name, ARM_CPU_NAME_LENGTH);
+  output_buf[ARM_CPU_NAME_LENGTH] = 0;
+
+  arg_pos = strchr (output_buf, '+');
+
+  /* If we found a '+' truncate the entry at that point.  */
+  if (arg_pos)
+    *arg_pos = '\0';
+
+  return output_buf;
+}
+
+/* Called by the driver to rewrite a name passed to the -march
+   argument in preparation to be passed to the assembler.  The
+   names passed from the command line will be in ARGV, we want
+   to use the right-most argument, which should be in
+   ARGV[ARGC - 1].  ARGC should always be greater than 0.  */
+
+const char *
+arm_rewrite_march (int argc, const char **argv)
+{
+  gcc_assert (argc);
+  return arm_rewrite_selected_arch (argv[argc - 1]);
+}
 
 #include "config/arm/arm-cpu-cdata.h"
 
@@ -122,26 +162,603 @@ check_isa_bits_for (const enum isa_feature* bits, enum isa_feature bit)
 
 /* Called by the driver to check whether the target denoted by current
    command line options is a Thumb-only target.  ARGV is an array of
-   -march and -mcpu values (ie. it contains the rhs after the equal
-   sign) and we use the last one of them to make a decision.  The
-   number of elements in ARGV is given in ARGC.  */
+   tupples (normally only one) where the first element of the tupple
+   is 'cpu' or 'arch' and the second is the option passed to the
+   compiler for that.  An architecture tupple is always taken in
+   preference to a cpu tupple and the last of each type always
+   overrides any earlier setting.  */
+
 const char *
 arm_target_thumb_only (int argc, const char **argv)
 {
-  unsigned int opt;
+  const char *arch = NULL;
+  const char *cpu = NULL;
+
+  if (argc % 2 != 0)
+    fatal_error (input_location,
+		 "%%:target_mode_check takes an even number of parameters");
+
+  while (argc)
+    {
+      if (strcmp (argv[0], "arch") == 0)
+	arch = argv[1];
+      else if (strcmp (argv[0], "cpu") == 0)
+	cpu = argv[1];
+      else
+	fatal_error (input_location,
+		     "unrecognized option passed to %%:target_mode_check");
+      argc -= 2;
+      argv += 2;
+    }
+
+  /* No architecture, or CPU, has option extensions that change
+     whether or not we have a Thumb-only device, so there is no need
+     to scan any option extensions specified.  */
+
+  /* If the architecture is specified, that overrides any CPU setting.  */
+  if (arch)
+    {
+      const arch_option *arch_opt
+	= arm_parse_arch_option_name (all_architectures, "-march", arch);
+
+      if (arch_opt && !check_isa_bits_for (arch_opt->common.isa_bits,
+					   isa_bit_notm))
+	return "-mthumb";
+    }
+  else if (cpu)
+    {
+      const cpu_option *cpu_opt
+	= arm_parse_cpu_option_name (all_cores, "-mcpu", cpu);
+
+      if (cpu_opt && !check_isa_bits_for (cpu_opt->common.isa_bits,
+					  isa_bit_notm))
+	return "-mthumb";
+    }
+
+  /* Compiler hasn't been configured with a default, and the CPU
+     doesn't require Thumb, so default to ARM.  */
+  return "-marm";
+}
+
+/* List the permitted CPU option names.  If TARGET is a near miss for an
+   entry, print out the suggested alternative.  */
+static void
+arm_print_hint_for_cpu_option (const char *target,
+			       const cpu_option *list)
+{
+  auto_vec<const char*> candidates;
+  for (; list->common.name != NULL; list++)
+    candidates.safe_push (list->common.name);
+  char *s;
+  const char *hint = candidates_list_and_hint (target, s, candidates);
+  if (hint)
+    inform (input_location, "valid arguments are: %s; did you mean %qs?",
+	    s, hint);
+  else
+    inform (input_location, "valid arguments are: %s", s);
+
+  XDELETEVEC (s);
+}
+
+/* Parse the base component of a CPU selection in LIST.  Return a
+   pointer to the entry in the architecture table.  OPTNAME is the
+   name of the option we are parsing and can be used if a diagnostic
+   is needed.  */
+const cpu_option *
+arm_parse_cpu_option_name (const cpu_option *list, const char *optname,
+			   const char *target)
+{
+  const cpu_option *entry;
+  const char *end  = strchr (target, '+');
+  size_t len = end ? end - target : strlen (target);
 
-  if (argc)
+  for (entry = list; entry->common.name != NULL; entry++)
     {
-      for (opt = 0; opt < (ARRAY_SIZE (arm_arch_core_flags)); opt++)
-	if ((strcmp (argv[argc - 1], arm_arch_core_flags[opt].name) == 0)
-	    && !check_isa_bits_for (arm_arch_core_flags[opt].isa_bits,
-				    isa_bit_notm))
-	  return "-mthumb";
+      if (strncmp (entry->common.name, target, len) == 0
+	  && entry->common.name[len] == '\0')
+	return entry;
+    }
+
+  error_at (input_location, "unrecognized %s target: %s", optname, target);
+  arm_print_hint_for_cpu_option (target, list);
+  return NULL;
+}
 
-      return NULL;
+/* List the permitted architecture option names.  If TARGET is a near
+   miss for an entry, print out the suggested alternative.  */
+static void
+arm_print_hint_for_arch_option (const char *target,
+			       const arch_option *list)
+{
+  auto_vec<const char*> candidates;
+  for (; list->common.name != NULL; list++)
+    candidates.safe_push (list->common.name);
+  char *s;
+  const char *hint = candidates_list_and_hint (target, s, candidates);
+  if (hint)
+    inform (input_location, "valid arguments are: %s; did you mean %qs?",
+	    s, hint);
+  else
+    inform (input_location, "valid arguments are: %s", s);
+
+  XDELETEVEC (s);
+}
+
+/* Parse the base component of a CPU or architecture selection in
+   LIST.  Return a pointer to the entry in the architecture table.
+   OPTNAME is the name of the option we are parsing and can be used if
+   a diagnostic is needed.  */
+const arch_option *
+arm_parse_arch_option_name (const arch_option *list, const char *optname,
+			    const char *target)
+{
+  const arch_option *entry;
+  const char *end  = strchr (target, '+');
+  size_t len = end ? end - target : strlen (target);
+
+  for (entry = list; entry->common.name != NULL; entry++)
+    {
+      if (strncmp (entry->common.name, target, len) == 0
+	  && entry->common.name[len] == '\0')
+	return entry;
     }
+
+  error_at (input_location, "unrecognized %s target: %s", optname, target);
+  arm_print_hint_for_arch_option (target, list);
+  return NULL;
+}
+
+/* List the permitted architecture option names.  If TARGET is a near
+   miss for an entry, print out the suggested alternative.  */
+static void
+arm_print_hint_for_fpu_option (const char *target)
+{
+  auto_vec<const char*> candidates;
+  for (int i = 0; i < TARGET_FPU_auto; i++)
+    candidates.safe_push (all_fpus[i].name);
+  char *s;
+  const char *hint = candidates_list_and_hint (target, s, candidates);
+  if (hint)
+    inform (input_location, "valid arguments are: %s; did you mean %qs?",
+	    s, hint);
   else
-    return NULL;
+    inform (input_location, "valid arguments are: %s", s);
+
+  XDELETEVEC (s);
+}
+
+static const arm_fpu_desc *
+arm_parse_fpu_option (const char *opt)
+{
+  int i;
+
+  for (i = 0; i < TARGET_FPU_auto; i++)
+    {
+      if (strcmp (all_fpus[i].name, opt) == 0)
+	return all_fpus + i;
+    }
+
+  error_at (input_location, "unrecognized -mfpu target: %s", opt);
+  arm_print_hint_for_fpu_option (opt);
+  return NULL;
+}
+
+/* Convert a static initializer array of feature bits to sbitmap
+   representation.  */
+void
+arm_initialize_isa (sbitmap isa, const enum isa_feature *isa_bits)
+{
+  bitmap_clear (isa);
+  while (*isa_bits != isa_nobit)
+    bitmap_set_bit (isa, *(isa_bits++));
+}
+
+/* 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 cpu_arch_option *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_arch_extension *list = target->extensions;
+       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.  */
+void
+arm_parse_option_features (sbitmap isa, const cpu_arch_option *target,
+			   const char *opts_in)
+{
+  const char *opts = opts_in;
+
+  if (!opts)
+    return;
+
+  if (!target->extensions)
+    {
+      error_at (input_location, "%s does not take any feature options",
+		target->name);
+      return;
+    }
+
+  while (opts)
+    {
+      gcc_assert (*opts == '+');
+      const struct cpu_arch_extension *entry;
+      const char *end = strchr (++opts, '+');
+      size_t len = end ? end - opts : strlen (opts);
+      bool matched = false;
+
+      for (entry = target->extensions;
+	   !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;
+    }
+}
+
+class candidate_extension
+{
+public:
+  const cpu_arch_extension *extension;
+  sbitmap isa_bits;
+  bool required;
+
+  candidate_extension (const cpu_arch_extension *ext, sbitmap bits)
+    : extension (ext), isa_bits (bits), required (true)
+    {}
+  ~candidate_extension ()
+    {
+      sbitmap_free (isa_bits);
+    }
+};
+
+/* Generate a canonical representation of the -march option from the
+   current -march string (if given) and other options on the command
+   line that might affect the architecture.  This aids multilib selection
+   by ensuring that:
+   a) the option is always present
+   b) only the minimal set of options are used
+   c) when there are multiple extensions, they are in a consistent order.
+
+   The options array consists of couplets of information where the
+   first item in each couplet is the string describing which option
+   name was selected (arch, cpu, fpu) and the second is the value
+   passed for that option.  */
+const char *
+arm_canon_arch_option (int argc, const char **argv)
+{
+  const char *arch = NULL;
+  const char *cpu = NULL;
+  const char *fpu = NULL;
+  const char *abi = NULL;
+  static char *canonical_arch = NULL;
+
+  /* Just in case we're called more than once.  */
+  if (canonical_arch)
+    {
+      free (canonical_arch);
+      canonical_arch = NULL;
+    }
+
+  if (argc & 1)
+    fatal_error (input_location,
+		 "%%:canon_for_mlib takes 1 or more pairs of parameters");
+
+  while (argc)
+    {
+      if (strcmp (argv[0], "arch") == 0)
+	arch = argv[1];
+      else if (strcmp (argv[0], "cpu") == 0)
+	cpu = argv[1];
+      else if (strcmp (argv[0], "fpu") == 0)
+	fpu = argv[1];
+      else if (strcmp (argv[0], "abi") == 0)
+	abi = argv[1];
+      else
+	fatal_error (input_location,
+		     "unrecognized operand to %%:canon_for_mlib");
+
+      argc -= 2;
+      argv += 2;
+    }
+
+  auto_sbitmap target_isa (isa_num_bits);
+  auto_sbitmap base_isa (isa_num_bits);
+  auto_sbitmap fpu_isa (isa_num_bits);
+
+  bitmap_clear (fpu_isa);
+
+  const arch_option *selected_arch = NULL;
+
+  /* At least one of these must be defined by either the specs or the
+     user.  */
+  gcc_assert (cpu || arch);
+
+  if (!fpu)
+    fpu = FPUTYPE_AUTO;
+
+  if (!abi)
+    {
+      if (TARGET_DEFAULT_FLOAT_ABI == ARM_FLOAT_ABI_SOFT)
+	abi = "soft";
+      else if (TARGET_DEFAULT_FLOAT_ABI == ARM_FLOAT_ABI_SOFTFP)
+	abi = "softfp";
+      else if (TARGET_DEFAULT_FLOAT_ABI == ARM_FLOAT_ABI_HARD)
+	abi = "hard";
+    }
+
+  /* First build up a bitmap describing the target architecture.  */
+  if (arch)
+    {
+      selected_arch = arm_parse_arch_option_name (all_architectures,
+						  "-march", arch);
+
+      if (selected_arch == NULL)
+	return "";
+
+      arm_initialize_isa (target_isa, selected_arch->common.isa_bits);
+      arm_parse_option_features (target_isa, &selected_arch->common,
+				 strchr (arch, '+'));
+      if (fpu && strcmp (fpu, "auto") != 0)
+	{
+	  /* We assume that architectures do not have any FPU bits
+	     enabled by default.  If they did, we would need to strip
+	     these out first.  */
+	  const arm_fpu_desc *target_fpu = arm_parse_fpu_option (fpu);
+	  if (target_fpu == NULL)
+	    return "";
+
+	  arm_initialize_isa (fpu_isa, target_fpu->isa_bits);
+	  bitmap_ior (target_isa, target_isa, fpu_isa);
+	}
+    }
+  else if (cpu)
+    {
+      const cpu_option *selected_cpu
+	= arm_parse_cpu_option_name (all_cores, "-mcpu", cpu);
+
+      if (selected_cpu == NULL)
+	return "";
+
+      arm_initialize_isa (target_isa, selected_cpu->common.isa_bits);
+      arm_parse_option_features (target_isa, &selected_cpu->common,
+				 strchr (cpu, '+'));
+      if (fpu && strcmp (fpu, "auto") != 0)
+	{
+	  /* 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
+	     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".  */
+	  bool default_fpu_found = false;
+	  if (selected_cpu->common.extensions)
+	    {
+	      const cpu_arch_extension *ext;
+	      for (ext = selected_cpu->common.extensions; ext->name != NULL;
+		   ++ext)
+		{
+		  if (ext->remove
+		      && 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);
+		      default_fpu_found = true;
+		    }
+		}
+
+	    }
+
+	  if (!default_fpu_found)
+	    {
+	      arm_initialize_isa
+		(fpu_isa,
+		 all_fpus[TARGET_FPU_crypto_neon_fp_armv8].isa_bits);
+	      bitmap_and_compl (target_isa, target_isa, fpu_isa);
+	    }
+
+	  const arm_fpu_desc *target_fpu = arm_parse_fpu_option (fpu);
+	  if (target_fpu == NULL)
+	    return "";
+
+	  arm_initialize_isa (fpu_isa, target_fpu->isa_bits);
+	  bitmap_ior (target_isa, target_isa, fpu_isa);
+	}
+
+      selected_arch = all_architectures + selected_cpu->arch;
+    }
+
+  /* If we have a soft-float ABI, disable the FPU.  */
+  if (abi && strcmp (abi, "soft") == 0)
+    {
+      /* 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);
+    }
+
+  /* If we don't have a selected architecture by now, something's
+     badly wrong.  */
+  gcc_assert (selected_arch);
+
+  arm_initialize_isa (base_isa, selected_arch->common.isa_bits);
+
+  /* Architecture has no extension options, so just return the canonical
+     architecture name.  */
+  if (selected_arch->common.extensions == NULL)
+    return selected_arch->common.name;
+
+  /* We're only interested in extension bits.  */
+  bitmap_and_compl (target_isa, target_isa, base_isa);
+
+  /* There are no extensions needed.  Just return the canonical architecture
+     name.  */
+  if (bitmap_empty_p (target_isa))
+    return selected_arch->common.name;
+
+  /* What is left is the architecture that the compiler will target.  We
+     now need to map that back into a suitable option+features list.
+
+     The list is built in two passes.  First we scan every additive
+     option feature supported by the architecture.  If the option
+     provides a subset of the features we need we add it to the list
+     of candidates.  We then scan backwards over the list of
+     candidates and if we find a feature that adds nothing to one that
+     was later in the list we mark it as redundant.  The result is a
+     minimal list of required features for the target
+     architecture.  */
+
+  std::list<candidate_extension *> extensions;
+
+  auto_sbitmap target_isa_unsatisfied (isa_num_bits);
+  bitmap_copy (target_isa_unsatisfied, target_isa);
+
+  sbitmap isa_bits = NULL;
+  for (const cpu_arch_extension *cand = selected_arch->common.extensions;
+       cand->name != NULL;
+       cand++)
+    {
+      if (cand->remove || cand->alias)
+	continue;
+
+      if (isa_bits == NULL)
+	isa_bits = sbitmap_alloc (isa_num_bits);
+
+      arm_initialize_isa (isa_bits, cand->isa_bits);
+      if (bitmap_subset_p (isa_bits, target_isa))
+	{
+	  extensions.push_back (new candidate_extension (cand, isa_bits));
+	  bitmap_and_compl (target_isa_unsatisfied, target_isa_unsatisfied,
+			    isa_bits);
+	  isa_bits = NULL;
+	}
+    }
+
+  /* There's one extra case to consider, which is that the user has
+     specified an FPU that is less capable than this architecture
+     supports.  In that case the code above will fail to find a
+     suitable feature.  We handle this by scanning the list of options
+     again, matching the first option that provides an FPU that is
+     more capable than the selected FPU.
+
+     Note that the other case (user specified a more capable FPU than
+     this architecture supports) should end up selecting the most
+     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))
+    {
+      std::list<candidate_extension *>::iterator ipoint = extensions.begin ();
+
+      for (const cpu_arch_extension *cand = selected_arch->common.extensions;
+	   cand->name != NULL;
+	   cand++)
+	{
+	  if (cand->remove || cand->alias)
+	    continue;
+
+	  if (isa_bits == NULL)
+	    isa_bits = sbitmap_alloc (isa_num_bits);
+
+	  /* We need to keep the features in canonical order, so move the
+	     insertion point if this feature is a candidate.  */
+	  if (ipoint != extensions.end ()
+	      && (*ipoint)->extension == cand)
+	    ++ipoint;
+
+	  arm_initialize_isa (isa_bits, cand->isa_bits);
+	  if (bitmap_subset_p (fpu_isa, isa_bits))
+	    {
+	      extensions.insert (ipoint,
+				 new candidate_extension (cand, isa_bits));
+	      isa_bits = NULL;
+	      break;
+	    }
+	}
+    }
+
+  if (isa_bits)
+    sbitmap_free (isa_bits);
+
+  bitmap_clear (target_isa);
+  size_t len = 1;
+  for (std::list<candidate_extension *>::reverse_iterator riter
+	 = extensions.rbegin ();
+       riter != extensions.rend (); ++riter)
+    {
+      if (bitmap_subset_p ((*riter)->isa_bits, target_isa))
+	(*riter)->required = false;
+      else
+	{
+	  bitmap_ior (target_isa, target_isa, (*riter)->isa_bits);
+	  len += strlen ((*riter)->extension->name) + 1;
+	}
+    }
+
+  canonical_arch
+    = (char *) xmalloc (len + strlen (selected_arch->common.name));
+
+  strcpy (canonical_arch, selected_arch->common.name);
+
+  for (std::list<candidate_extension *>::iterator iter = extensions.begin ();
+       iter != extensions.end (); ++iter)
+    {
+      if ((*iter)->required)
+	{
+	  strcat (canonical_arch, "+");
+	  strcat (canonical_arch, (*iter)->extension->name);
+	}
+      delete (*iter);
+    }
+
+  return canonical_arch;
 }
 
 #undef ARM_CPU_NAME_LENGTH
diff --git a/gcc/config.gcc b/gcc/config.gcc
index f55dcaa..967ea77 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1158,8 +1158,8 @@ arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtems* | arm*-*-fuchsia*)
 	  ;;
 	arm*-*-fuchsia*)
 	  tm_file="${tm_file} fuchsia.h arm/fuchsia-elf.h glibc-stdint.h"
-	  tmake_file="${tmake_file} arm/t-bpabi"
-	  target_cpu_cname="genericv7a"
+	  tmake_file="${tmake_file} arm/t-bpabi arm/t-fuchsia"
+	  target_cpu_cname="generic-armv7-a"
 	  ;;
 	arm*-*-rtems*)
 	  tm_file="${tm_file} rtems.h arm/rtems.h newlib-stdint.h"
@@ -3854,11 +3854,15 @@ case "${target}" in
 				    echo "Error: You cannot use any of --with-arch/cpu/fpu/float/mode with --with-multilib-list=${with_multilib_list}" 1>&2
 				    exit 1
 				fi
-
+				# But pass the default value for float-abi
+				# through to the multilib selector
+				with_float="soft"
 				tmake_file="${tmake_file} ${tmake_profile_file}"
 				TM_MULTILIB_CONFIG="$with_multilib_list"
 			fi
 		fi
+		target_cpu_cname=${target_cpu_cname:-arm6}
+		with_cpu=${with_cpu:-$target_cpu_cname}
 		;;
 
 	fr*-*-*linux*)
@@ -4492,11 +4496,12 @@ case ${target} in
 		;;
 
 	arm*-*-*)
-		if test x$target_cpu_cname = x
+		if test x$with_cpu = x
 		then
-			target_cpu_default2=TARGET_CPU_arm6
+			echo "Don't know the target cpu" 1>&2
+			exit 1
 		else
-			target_cpu_default2=TARGET_CPU_$target_cpu_cname
+			target_cpu_default2="\\\"$with_cpu\\\""
 		fi
 		;;
 
diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index a0569ed..9755189 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -1876,7 +1876,7 @@ arm_init_builtins (void)
      arm_init_neon_builtins which uses it.  */
   arm_init_fp16_builtins ();
 
-  if (TARGET_HARD_FLOAT)
+  if (TARGET_MAYBE_HARD_FLOAT)
     {
       arm_init_neon_builtins ();
       arm_init_vfp_builtins ();
@@ -1885,7 +1885,7 @@ arm_init_builtins (void)
 
   arm_init_acle_builtins ();
 
-  if (TARGET_HARD_FLOAT)
+  if (TARGET_MAYBE_HARD_FLOAT)
     {
       tree ftype_set_fpscr
 	= build_function_type_list (void_type_node, unsigned_type_node, NULL);
diff --git a/gcc/config/arm/arm-cpu-cdata.h b/gcc/config/arm/arm-cpu-cdata.h
index b388812..6cc2ea2 100644
--- a/gcc/config/arm/arm-cpu-cdata.h
+++ b/gcc/config/arm/arm-cpu-cdata.h
@@ -20,1039 +20,2607 @@
    License along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
-static const struct arm_arch_core_flag arm_arch_core_flags[] =
+static const cpu_arch_extension cpu_opttab_arm9e[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_arm946es[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_arm966es[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_arm968es[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_arm10e[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_arm1020e[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_arm1022e[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_arm926ejs[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_arm1026ejs[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_genericv7a[] = {
+  {
+    "vfpv3-d16", false, false,
+    { ISA_VFPv3,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "vfpv3", false, false,
+    { ISA_VFPv3,ISA_FP_D32, isa_nobit }
+  },
+  {
+    "vfpv3-d16-fp16", false, false,
+    { ISA_VFPv3,ISA_FP_DBL,isa_bit_fp16conv, isa_nobit }
+  },
+  {
+    "vfpv3-fp16", false, false,
+    { ISA_VFPv3,ISA_FP_D32,isa_bit_fp16conv, isa_nobit }
+  },
+  {
+    "vfpv4-d16", false, false,
+    { ISA_VFPv4,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "vfpv4", false, false,
+    { ISA_VFPv4,ISA_FP_D32, isa_nobit }
+  },
+  {
+    "simd", false, false,
+    { ISA_VFPv3,ISA_NEON, isa_nobit }
+  },
+  {
+    "neon-fp16", false, false,
+    { ISA_VFPv3,ISA_NEON,isa_bit_fp16conv, isa_nobit }
+  },
+  {
+    "neon-vfpv4", false, false,
+    { ISA_VFPv4,ISA_NEON, isa_nobit }
+  },
+  {
+    "nosimd", true, false,
+    { ISA_ALL_SIMD, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  {
+    "neon", false, true, 
+    { ISA_VFPv3,ISA_NEON, isa_nobit }
+  },
+  {
+    "neon-vfpv3", false, true, 
+    { ISA_VFPv3,ISA_NEON, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa5[] = {
+  {
+    "nosimd", true, false,
+    { ISA_ALL_SIMD, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa7[] = {
+  {
+    "nosimd", true, false,
+    { ISA_ALL_SIMD, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa8[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa9[] = {
+  {
+    "nosimd", true, false,
+    { ISA_ALL_SIMD, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa12[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa15[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa17[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexr5[] = {
+  {
+    "nofp.dp", true, false,
+    { ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexr7[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexr8[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexm7[] = {
+  {
+    "nofp.dp", true, false,
+    { ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexm4[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa15cortexa7[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa17cortexa7[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa32[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa35[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa53[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa57[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa72[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa73[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_exynosm1[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_falkor[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_qdf24xx[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_xgene1[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa57cortexa53[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa72cortexa53[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa73cortexa35[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexa73cortexa53[] = {
+  {
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const cpu_arch_extension cpu_opttab_cortexm33[] = {
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+const cpu_option all_cores[] =
 {
   {
-    "arm2",
     {
-      ISA_ARMv2,isa_bit_mode26,
-      isa_nobit
+      "arm2",
+      NULL,
+      {
+        ISA_ARMv2,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv2
   },
   {
-    "arm250",
     {
-      ISA_ARMv2,isa_bit_mode26,
-      isa_nobit
+      "arm250",
+      NULL,
+      {
+        ISA_ARMv2,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv2
   },
   {
-    "arm3",
     {
-      ISA_ARMv2,isa_bit_mode26,
-      isa_nobit
+      "arm3",
+      NULL,
+      {
+        ISA_ARMv2,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv2
   },
   {
-    "arm6",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "arm6",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv3
   },
   {
-    "arm60",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "arm60",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv3
   },
   {
-    "arm600",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "arm600",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv3
   },
   {
-    "arm610",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "arm610",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv3
   },
   {
-    "arm620",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "arm620",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv3
   },
   {
-    "arm7",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "arm7",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv3
   },
   {
-    "arm7d",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "arm7d",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv3
   },
   {
-    "arm7di",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "arm7di",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv3
   },
   {
-    "arm70",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "arm70",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv3
   },
   {
-    "arm700",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "arm700",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv3
   },
   {
-    "arm700i",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "arm700i",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv3
   },
   {
-    "arm710",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "arm710",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv3
+  },
+  {
+    {
+      "arm720",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv3
+  },
+  {
+    {
+      "arm710c",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv3
+  },
+  {
+    {
+      "arm7100",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv3
+  },
+  {
+    {
+      "arm7500",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv3
+  },
+  {
+    {
+      "arm7500fe",
+      NULL,
+      {
+        ISA_ARMv3,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv3
+  },
+  {
+    {
+      "arm7m",
+      NULL,
+      {
+        ISA_ARMv3m,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv3m
+  },
+  {
+    {
+      "arm7dm",
+      NULL,
+      {
+        ISA_ARMv3m,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv3m
+  },
+  {
+    {
+      "arm7dmi",
+      NULL,
+      {
+        ISA_ARMv3m,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv3m
+  },
+  {
+    {
+      "arm8",
+      NULL,
+      {
+        ISA_ARMv4,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4
+  },
+  {
+    {
+      "arm810",
+      NULL,
+      {
+        ISA_ARMv4,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4
+  },
+  {
+    {
+      "strongarm",
+      NULL,
+      {
+        ISA_ARMv4,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4
+  },
+  {
+    {
+      "strongarm110",
+      NULL,
+      {
+        ISA_ARMv4,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4
+  },
+  {
+    {
+      "strongarm1100",
+      NULL,
+      {
+        ISA_ARMv4,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4
+  },
+  {
+    {
+      "strongarm1110",
+      NULL,
+      {
+        ISA_ARMv4,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4
+  },
+  {
+    {
+      "fa526",
+      NULL,
+      {
+        ISA_ARMv4,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4
+  },
+  {
+    {
+      "fa626",
+      NULL,
+      {
+        ISA_ARMv4,isa_bit_mode26,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4
+  },
+  {
+    {
+      "arm7tdmi",
+      NULL,
+      {
+        ISA_ARMv4t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4t
+  },
+  {
+    {
+      "arm7tdmi-s",
+      NULL,
+      {
+        ISA_ARMv4t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4t
+  },
+  {
+    {
+      "arm710t",
+      NULL,
+      {
+        ISA_ARMv4t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4t
+  },
+  {
+    {
+      "arm720t",
+      NULL,
+      {
+        ISA_ARMv4t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4t
+  },
+  {
+    {
+      "arm740t",
+      NULL,
+      {
+        ISA_ARMv4t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4t
+  },
+  {
+    {
+      "arm9",
+      NULL,
+      {
+        ISA_ARMv4t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4t
+  },
+  {
+    {
+      "arm9tdmi",
+      NULL,
+      {
+        ISA_ARMv4t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4t
+  },
+  {
+    {
+      "arm920",
+      NULL,
+      {
+        ISA_ARMv4t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4t
+  },
+  {
+    {
+      "arm920t",
+      NULL,
+      {
+        ISA_ARMv4t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4t
+  },
+  {
+    {
+      "arm922t",
+      NULL,
+      {
+        ISA_ARMv4t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4t
+  },
+  {
+    {
+      "arm940t",
+      NULL,
+      {
+        ISA_ARMv4t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4t
+  },
+  {
+    {
+      "ep9312",
+      NULL,
+      {
+        ISA_ARMv4t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv4t
+  },
+  {
+    {
+      "arm10tdmi",
+      NULL,
+      {
+        ISA_ARMv5t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv5t
+  },
+  {
+    {
+      "arm1020t",
+      NULL,
+      {
+        ISA_ARMv5t,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv5t
+  },
+  {
+    {
+      "arm9e",
+      cpu_opttab_arm9e,
+      {
+        ISA_ARMv5te,
+        ISA_VFPv2,ISA_FP_DBL,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv5te
+  },
+  {
+    {
+      "arm946e-s",
+      cpu_opttab_arm946es,
+      {
+        ISA_ARMv5te,
+        ISA_VFPv2,ISA_FP_DBL,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv5te
+  },
+  {
+    {
+      "arm966e-s",
+      cpu_opttab_arm966es,
+      {
+        ISA_ARMv5te,
+        ISA_VFPv2,ISA_FP_DBL,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv5te
+  },
+  {
+    {
+      "arm968e-s",
+      cpu_opttab_arm968es,
+      {
+        ISA_ARMv5te,
+        ISA_VFPv2,ISA_FP_DBL,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv5te
+  },
+  {
+    {
+      "arm10e",
+      cpu_opttab_arm10e,
+      {
+        ISA_ARMv5te,
+        ISA_VFPv2,ISA_FP_DBL,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv5te
+  },
+  {
+    {
+      "arm1020e",
+      cpu_opttab_arm1020e,
+      {
+        ISA_ARMv5te,
+        ISA_VFPv2,ISA_FP_DBL,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv5te
+  },
+  {
+    {
+      "arm1022e",
+      cpu_opttab_arm1022e,
+      {
+        ISA_ARMv5te,
+        ISA_VFPv2,ISA_FP_DBL,
+        isa_nobit
+      }
+    },
+    TARGET_ARCH_armv5te
+  },
+  {
+    {
+      "xscale",
+      NULL,
+      {
+        ISA_ARMv5te,
+        isa_bit_xscale,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv5te
   },
   {
-    "arm720",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "iwmmxt",
+      NULL,
+      {
+        ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_iwmmxt
   },
   {
-    "arm710c",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "iwmmxt2",
+      NULL,
+      {
+        ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,isa_bit_iwmmxt2,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_iwmmxt2
   },
   {
-    "arm7100",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "fa606te",
+      NULL,
+      {
+        ISA_ARMv5te,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv5te
   },
   {
-    "arm7500",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "fa626te",
+      NULL,
+      {
+        ISA_ARMv5te,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv5te
   },
   {
-    "arm7500fe",
     {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
+      "fmp626",
+      NULL,
+      {
+        ISA_ARMv5te,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv5te
   },
   {
-    "arm7m",
     {
-      ISA_ARMv3m,isa_bit_mode26,
-      isa_nobit
+      "fa726te",
+      NULL,
+      {
+        ISA_ARMv5te,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv5te
   },
   {
-    "arm7dm",
     {
-      ISA_ARMv3m,isa_bit_mode26,
-      isa_nobit
+      "arm926ej-s",
+      cpu_opttab_arm926ejs,
+      {
+        ISA_ARMv5tej,
+        ISA_VFPv2,ISA_FP_DBL,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv5tej
   },
   {
-    "arm7dmi",
     {
-      ISA_ARMv3m,isa_bit_mode26,
-      isa_nobit
+      "arm1026ej-s",
+      cpu_opttab_arm1026ejs,
+      {
+        ISA_ARMv5tej,
+        ISA_VFPv2,ISA_FP_DBL,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv5tej
   },
   {
-    "arm8",
     {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
+      "arm1136j-s",
+      NULL,
+      {
+        ISA_ARMv6j,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6j
   },
   {
-    "arm810",
     {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
+      "arm1136jf-s",
+      NULL,
+      {
+        ISA_ARMv6j,
+        ISA_VFPv2,ISA_FP_DBL,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6j
   },
   {
-    "strongarm",
     {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
+      "arm1176jz-s",
+      NULL,
+      {
+        ISA_ARMv6kz,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6kz
   },
   {
-    "strongarm110",
     {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
+      "arm1176jzf-s",
+      NULL,
+      {
+        ISA_ARMv6kz,
+        ISA_VFPv2,ISA_FP_DBL,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6kz
   },
   {
-    "strongarm1100",
     {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
+      "mpcorenovfp",
+      NULL,
+      {
+        ISA_ARMv6k,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6k
   },
   {
-    "strongarm1110",
     {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
+      "mpcore",
+      NULL,
+      {
+        ISA_ARMv6k,
+        ISA_VFPv2,ISA_FP_DBL,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6k
   },
   {
-    "fa526",
     {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
+      "arm1156t2-s",
+      NULL,
+      {
+        ISA_ARMv6t2,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6t2
   },
   {
-    "fa626",
     {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
+      "arm1156t2f-s",
+      NULL,
+      {
+        ISA_ARMv6t2,
+        ISA_VFPv2,ISA_FP_DBL,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6t2
   },
   {
-    "arm7tdmi",
     {
-      ISA_ARMv4t,
-      isa_nobit
+      "cortex-m1",
+      NULL,
+      {
+        ISA_ARMv6m,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6_m
   },
   {
-    "arm7tdmi-s",
     {
-      ISA_ARMv4t,
-      isa_nobit
+      "cortex-m0",
+      NULL,
+      {
+        ISA_ARMv6m,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6_m
   },
   {
-    "arm710t",
     {
-      ISA_ARMv4t,
-      isa_nobit
+      "cortex-m0plus",
+      NULL,
+      {
+        ISA_ARMv6m,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6_m
   },
   {
-    "arm720t",
     {
-      ISA_ARMv4t,
-      isa_nobit
+      "cortex-m1.small-multiply",
+      NULL,
+      {
+        ISA_ARMv6m,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6_m
   },
   {
-    "arm740t",
     {
-      ISA_ARMv4t,
-      isa_nobit
+      "cortex-m0.small-multiply",
+      NULL,
+      {
+        ISA_ARMv6m,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6_m
   },
   {
-    "arm9",
     {
-      ISA_ARMv4t,
-      isa_nobit
+      "cortex-m0plus.small-multiply",
+      NULL,
+      {
+        ISA_ARMv6m,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv6_m
   },
   {
-    "arm9tdmi",
     {
-      ISA_ARMv4t,
-      isa_nobit
+      "generic-armv7-a",
+      cpu_opttab_genericv7a,
+      {
+        ISA_ARMv7a,
+        ISA_VFPv3,ISA_FP_DBL,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7_a
   },
   {
-    "arm920",
     {
-      ISA_ARMv4t,
-      isa_nobit
+      "cortex-a5",
+      cpu_opttab_cortexa5,
+      {
+        ISA_ARMv7a,
+        ISA_VFPv3,ISA_NEON,isa_bit_fp16conv,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7_a
   },
   {
-    "arm920t",
     {
-      ISA_ARMv4t,
-      isa_nobit
+      "cortex-a7",
+      cpu_opttab_cortexa7,
+      {
+        ISA_ARMv7ve,
+        ISA_VFPv4,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7ve
   },
   {
-    "arm922t",
     {
-      ISA_ARMv4t,
-      isa_nobit
+      "cortex-a8",
+      cpu_opttab_cortexa8,
+      {
+        ISA_ARMv7a,
+        ISA_VFPv3,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7_a
   },
   {
-    "arm940t",
     {
-      ISA_ARMv4t,
-      isa_nobit
+      "cortex-a9",
+      cpu_opttab_cortexa9,
+      {
+        ISA_ARMv7a,
+        ISA_VFPv3,ISA_NEON,isa_bit_fp16conv,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7_a
   },
   {
-    "ep9312",
     {
-      ISA_ARMv4t,
-      isa_nobit
+      "cortex-a12",
+      cpu_opttab_cortexa12,
+      {
+        ISA_ARMv7ve,
+        ISA_VFPv4,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7ve
   },
   {
-    "arm10tdmi",
     {
-      ISA_ARMv5t,
-      isa_nobit
+      "cortex-a15",
+      cpu_opttab_cortexa15,
+      {
+        ISA_ARMv7ve,
+        ISA_VFPv4,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7ve
   },
   {
-    "arm1020t",
     {
-      ISA_ARMv5t,
-      isa_nobit
+      "cortex-a17",
+      cpu_opttab_cortexa17,
+      {
+        ISA_ARMv7ve,
+        ISA_VFPv4,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7ve
   },
   {
-    "arm9e",
     {
-      ISA_ARMv5te,
-      isa_nobit
+      "cortex-r4",
+      NULL,
+      {
+        ISA_ARMv7r,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7_r
   },
   {
-    "arm946e-s",
     {
-      ISA_ARMv5te,
-      isa_nobit
+      "cortex-r4f",
+      NULL,
+      {
+        ISA_ARMv7r,
+        ISA_VFPv3,ISA_FP_DBL,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7_r
   },
   {
-    "arm966e-s",
     {
-      ISA_ARMv5te,
-      isa_nobit
+      "cortex-r5",
+      cpu_opttab_cortexr5,
+      {
+        ISA_ARMv7r,
+        isa_bit_adiv,
+        ISA_VFPv3,ISA_FP_DBL,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7_r
   },
   {
-    "arm968e-s",
     {
-      ISA_ARMv5te,
-      isa_nobit
+      "cortex-r7",
+      cpu_opttab_cortexr7,
+      {
+        ISA_ARMv7r,
+        isa_bit_adiv,
+        ISA_VFPv3,ISA_FP_DBL,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7_r
   },
   {
-    "arm10e",
     {
-      ISA_ARMv5te,
-      isa_nobit
+      "cortex-r8",
+      cpu_opttab_cortexr8,
+      {
+        ISA_ARMv7r,
+        isa_bit_adiv,
+        ISA_VFPv3,ISA_FP_DBL,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7_r
   },
   {
-    "arm1020e",
     {
-      ISA_ARMv5te,
-      isa_nobit
+      "cortex-m7",
+      cpu_opttab_cortexm7,
+      {
+        ISA_ARMv7em,
+        ISA_FPv5,ISA_FP_DBL,
+        isa_quirk_no_volatile_ce,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7e_m
   },
   {
-    "arm1022e",
     {
-      ISA_ARMv5te,
-      isa_nobit
+      "cortex-m4",
+      cpu_opttab_cortexm4,
+      {
+        ISA_ARMv7em,
+        ISA_VFPv4,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7e_m
   },
   {
-    "xscale",
     {
-      ISA_ARMv5te,
-      isa_bit_xscale,
-      isa_nobit
+      "cortex-m3",
+      NULL,
+      {
+        ISA_ARMv7m,
+        isa_quirk_cm3_ldrd,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7_m
   },
   {
-    "iwmmxt",
     {
-      ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,
-      isa_nobit
+      "marvell-pj4",
+      NULL,
+      {
+        ISA_ARMv7a,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7_a
   },
   {
-    "iwmmxt2",
     {
-      ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,isa_bit_iwmmxt2,
-      isa_nobit
+      "cortex-a15.cortex-a7",
+      cpu_opttab_cortexa15cortexa7,
+      {
+        ISA_ARMv7ve,
+        ISA_VFPv4,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7ve
   },
   {
-    "fa606te",
     {
-      ISA_ARMv5te,
-      isa_nobit
+      "cortex-a17.cortex-a7",
+      cpu_opttab_cortexa17cortexa7,
+      {
+        ISA_ARMv7ve,
+        ISA_VFPv4,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv7ve
   },
   {
-    "fa626te",
     {
-      ISA_ARMv5te,
-      isa_nobit
+      "cortex-a32",
+      cpu_opttab_cortexa32,
+      {
+        ISA_ARMv8a,
+        isa_bit_crc32,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "fmp626",
     {
-      ISA_ARMv5te,
-      isa_nobit
+      "cortex-a35",
+      cpu_opttab_cortexa35,
+      {
+        ISA_ARMv8a,
+        isa_bit_crc32,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "fa726te",
     {
-      ISA_ARMv5te,
-      isa_nobit
+      "cortex-a53",
+      cpu_opttab_cortexa53,
+      {
+        ISA_ARMv8a,
+        isa_bit_crc32,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "arm926ej-s",
     {
-      ISA_ARMv5tej,
-      isa_nobit
+      "cortex-a57",
+      cpu_opttab_cortexa57,
+      {
+        ISA_ARMv8a,
+        isa_bit_crc32,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "arm1026ej-s",
     {
-      ISA_ARMv5tej,
-      isa_nobit
+      "cortex-a72",
+      cpu_opttab_cortexa72,
+      {
+        ISA_ARMv8a,
+        isa_bit_crc32,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "arm1136j-s",
     {
-      ISA_ARMv6j,
-      isa_nobit
+      "cortex-a73",
+      cpu_opttab_cortexa73,
+      {
+        ISA_ARMv8a,
+        isa_bit_crc32,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "arm1136jf-s",
     {
-      ISA_ARMv6j,
-      ISA_VFPv2,ISA_FP_DBL,
-      isa_nobit
+      "exynos-m1",
+      cpu_opttab_exynosm1,
+      {
+        ISA_ARMv8a,
+        isa_bit_crc32,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "arm1176jz-s",
     {
-      ISA_ARMv6kz,
-      isa_nobit
+      "falkor",
+      cpu_opttab_falkor,
+      {
+        ISA_ARMv8a,
+        isa_bit_crc32,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "arm1176jzf-s",
     {
-      ISA_ARMv6kz,
-      ISA_VFPv2,ISA_FP_DBL,
-      isa_nobit
+      "qdf24xx",
+      cpu_opttab_qdf24xx,
+      {
+        ISA_ARMv8a,
+        isa_bit_crc32,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "mpcorenovfp",
     {
-      ISA_ARMv6k,
-      isa_nobit
+      "xgene1",
+      cpu_opttab_xgene1,
+      {
+        ISA_ARMv8a,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "mpcore",
     {
-      ISA_ARMv6k,
-      ISA_VFPv2,ISA_FP_DBL,
-      isa_nobit
+      "cortex-a57.cortex-a53",
+      cpu_opttab_cortexa57cortexa53,
+      {
+        ISA_ARMv8a,
+        isa_bit_crc32,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "arm1156t2-s",
     {
-      ISA_ARMv6t2,
-      isa_nobit
+      "cortex-a72.cortex-a53",
+      cpu_opttab_cortexa72cortexa53,
+      {
+        ISA_ARMv8a,
+        isa_bit_crc32,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "arm1156t2f-s",
     {
-      ISA_ARMv6t2,
-      ISA_VFPv2,ISA_FP_DBL,
-      isa_nobit
+      "cortex-a73.cortex-a35",
+      cpu_opttab_cortexa73cortexa35,
+      {
+        ISA_ARMv8a,
+        isa_bit_crc32,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "cortex-m1",
     {
-      ISA_ARMv6m,
-      isa_nobit
+      "cortex-a73.cortex-a53",
+      cpu_opttab_cortexa73cortexa53,
+      {
+        ISA_ARMv8a,
+        isa_bit_crc32,
+        ISA_FP_ARMv8,ISA_NEON,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_a
   },
   {
-    "cortex-m0",
     {
-      ISA_ARMv6m,
-      isa_nobit
+      "cortex-m23",
+      NULL,
+      {
+        ISA_ARMv8m_base,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_m_base
   },
   {
-    "cortex-m0plus",
     {
-      ISA_ARMv6m,
-      isa_nobit
+      "cortex-m33",
+      cpu_opttab_cortexm33,
+      {
+        ISA_ARMv8m_main,
+        isa_bit_ARMv7em,
+        ISA_FPv5,
+        isa_nobit
+      }
     },
+    TARGET_ARCH_armv8_m_main
+  },
+  {{NULL, NULL, {isa_nobit}}, TARGET_ARCH_arm_none}
+};
+static const struct cpu_arch_extension arch_opttab_armv5e[] = {
+  {
+    "fp", false, false,
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  {
+    "vfpv2", false, true, 
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv5te[] = {
+  {
+    "fp", false, false,
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  {
+    "vfpv2", false, true, 
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv5tej[] = {
+  {
+    "fp", false, false,
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  {
+    "vfpv2", false, true, 
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv6[] = {
+  {
+    "fp", false, false,
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  {
+    "vfpv2", false, true, 
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv6j[] = {
+  {
+    "fp", false, false,
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  {
+    "vfpv2", false, true, 
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv6k[] = {
+  {
+    "fp", false, false,
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  {
+    "vfpv2", false, true, 
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv6z[] = {
+  {
+    "fp", false, false,
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  {
+    "vfpv2", false, true, 
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv6kz[] = {
+  {
+    "fp", false, false,
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  {
+    "vfpv2", false, true, 
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv6zk[] = {
+  {
+    "fp", false, false,
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  {
+    "vfpv2", false, true, 
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv6t2[] = {
+  {
+    "fp", false, false,
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  {
+    "vfpv2", false, true, 
+    { ISA_VFPv2,ISA_FP_DBL, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv7[] = {
+  {
+    "fp", false, false,
+    { ISA_VFPv3,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  {
+    "vfpv3-d16", false, true, 
+    { ISA_VFPv3,ISA_FP_DBL, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv7_a[] = {
+  {
+    "fp", false, false,
+    { ISA_VFPv3,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "vfpv3", false, false,
+    { ISA_VFPv3,ISA_FP_D32, isa_nobit }
+  },
+  {
+    "vfpv3-d16-fp16", false, false,
+    { ISA_VFPv3,ISA_FP_DBL,isa_bit_fp16conv, isa_nobit }
+  },
+  {
+    "vfpv3-fp16", false, false,
+    { ISA_VFPv3,ISA_FP_DBL,ISA_FP_D32,isa_bit_fp16conv, isa_nobit }
+  },
+  {
+    "vfpv4-d16", false, false,
+    { ISA_VFPv4,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "vfpv4", false, false,
+    { ISA_VFPv4,ISA_FP_D32, isa_nobit }
+  },
+  {
+    "simd", false, false,
+    { ISA_VFPv3,ISA_NEON, isa_nobit }
+  },
+  {
+    "neon-fp16", false, false,
+    { ISA_VFPv3,ISA_NEON,isa_bit_fp16conv, isa_nobit }
+  },
+  {
+    "neon-vfpv4", false, false,
+    { ISA_VFPv4,ISA_NEON, isa_nobit }
+  },
+  {
+    "nosimd", true, false,
+    { ISA_ALL_SIMD, isa_nobit }
+  },
+  {
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
+  },
+  {
+    "vfpv3-d16", false, true, 
+    { ISA_VFPv3,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "neon", false, true, 
+    { ISA_VFPv3,ISA_NEON, isa_nobit }
+  },
+  {
+    "neon-vfpv3", false, true, 
+    { ISA_VFPv3,ISA_NEON, isa_nobit }
+  },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv7ve[] = {
+  {
+    "vfpv3-d16", false, false,
+    { ISA_VFPv3,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "vfpv3", false, false,
+    { ISA_VFPv3,ISA_FP_D32, isa_nobit }
+  },
+  {
+    "vfpv3-d16-fp16", false, false,
+    { ISA_VFPv3,ISA_FP_DBL,isa_bit_fp16conv, isa_nobit }
+  },
+  {
+    "vfpv3-fp16", false, false,
+    { ISA_VFPv3,ISA_FP_DBL,ISA_FP_D32,isa_bit_fp16conv, isa_nobit }
+  },
+  {
+    "fp", false, false,
+    { ISA_VFPv4,ISA_FP_DBL, isa_nobit }
+  },
+  {
+    "vfpv4", false, false,
+    { ISA_VFPv4,ISA_FP_D32, isa_nobit }
+  },
+  {
+    "neon", false, false,
+    { ISA_VFPv3,ISA_NEON, isa_nobit }
+  },
+  {
+    "neon-fp16", false, false,
+    { ISA_VFPv3,ISA_NEON,isa_bit_fp16conv, isa_nobit }
   },
   {
-    "cortex-m1.small-multiply",
-    {
-      ISA_ARMv6m,
-      isa_nobit
-    },
+    "simd", false, false,
+    { ISA_VFPv4,ISA_NEON, isa_nobit }
   },
   {
-    "cortex-m0.small-multiply",
-    {
-      ISA_ARMv6m,
-      isa_nobit
-    },
+    "nosimd", true, false,
+    { ISA_ALL_SIMD, isa_nobit }
   },
   {
-    "cortex-m0plus.small-multiply",
-    {
-      ISA_ARMv6m,
-      isa_nobit
-    },
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
   },
   {
-    "generic-armv7-a",
-    {
-      ISA_ARMv7a,
-      isa_nobit
-    },
+    "vfpv4-d16", false, true, 
+    { ISA_VFPv4,ISA_FP_DBL, isa_nobit }
   },
   {
-    "cortex-a5",
-    {
-      ISA_ARMv7a,
-      isa_nobit
-    },
+    "neon-vfpv3", false, true, 
+    { ISA_VFPv3,ISA_NEON, isa_nobit }
   },
   {
-    "cortex-a7",
-    {
-      ISA_ARMv7ve,
-      isa_nobit
-    },
+    "neon-vfpv4", false, true, 
+    { ISA_VFPv4,ISA_NEON, isa_nobit }
   },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv7_r[] = {
   {
-    "cortex-a8",
-    {
-      ISA_ARMv7a,
-      isa_nobit
-    },
+    "fp.sp", false, false,
+    { ISA_VFPv3, isa_nobit }
   },
   {
-    "cortex-a9",
-    {
-      ISA_ARMv7a,
-      isa_nobit
-    },
+    "fp", false, false,
+    { ISA_VFPv3,ISA_FP_DBL, isa_nobit }
   },
   {
-    "cortex-a12",
-    {
-      ISA_ARMv7ve,
-      isa_nobit
-    },
+    "idiv", false, false,
+    { isa_bit_adiv, isa_nobit }
   },
   {
-    "cortex-a15",
-    {
-      ISA_ARMv7ve,
-      isa_nobit
-    },
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
   },
   {
-    "cortex-a17",
-    {
-      ISA_ARMv7ve,
-      isa_nobit
-    },
+    "noidiv", true, false,
+    { isa_bit_adiv, isa_nobit }
   },
   {
-    "cortex-r4",
-    {
-      ISA_ARMv7r,
-      isa_nobit
-    },
+    "vfpv3xd", false, true, 
+    { ISA_VFPv3, isa_nobit }
   },
   {
-    "cortex-r4f",
-    {
-      ISA_ARMv7r,
-      isa_nobit
-    },
+    "vfpv3-d16", false, true, 
+    { ISA_VFPv3,ISA_FP_DBL, isa_nobit }
   },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv7e_m[] = {
   {
-    "cortex-r5",
-    {
-      ISA_ARMv7r,
-      isa_bit_adiv,
-      isa_nobit
-    },
+    "fp", false, false,
+    { ISA_VFPv4, isa_nobit }
   },
   {
-    "cortex-r7",
-    {
-      ISA_ARMv7r,
-      isa_bit_adiv,
-      isa_nobit
-    },
+    "fpv5", false, false,
+    { ISA_FPv5, isa_nobit }
   },
   {
-    "cortex-r8",
-    {
-      ISA_ARMv7r,
-      isa_bit_adiv,
-      isa_nobit
-    },
+    "fp.dp", false, false,
+    { ISA_FPv5,ISA_FP_DBL, isa_nobit }
   },
   {
-    "cortex-m7",
-    {
-      ISA_ARMv7em,
-      isa_quirk_no_volatile_ce,
-      isa_nobit
-    },
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
   },
   {
-    "cortex-m4",
-    {
-      ISA_ARMv7em,
-      isa_nobit
-    },
+    "vfpv4-sp-d16", false, true, 
+    { ISA_VFPv4, isa_nobit }
   },
   {
-    "cortex-m3",
-    {
-      ISA_ARMv7m,
-      isa_quirk_cm3_ldrd,
-      isa_nobit
-    },
+    "fpv5-d16", false, true, 
+    { ISA_FPv5,ISA_FP_DBL, isa_nobit }
   },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv8_a[] = {
   {
-    "marvell-pj4",
-    {
-      ISA_ARMv7a,
-      isa_nobit
-    },
+    "crc", false, false,
+    { isa_bit_crc32, isa_nobit }
   },
   {
-    "cortex-a15.cortex-a7",
-    {
-      ISA_ARMv7ve,
-      isa_nobit
-    },
+    "simd", false, false,
+    { ISA_FP_ARMv8,ISA_NEON, isa_nobit }
   },
   {
-    "cortex-a17.cortex-a7",
-    {
-      ISA_ARMv7ve,
-      isa_nobit
-    },
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
   },
   {
-    "cortex-a32",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "nocrypto", true, false,
+    { ISA_ALL_CRYPTO, isa_nobit }
   },
   {
-    "cortex-a35",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
   },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv8_1_a[] = {
   {
-    "cortex-a53",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "simd", false, false,
+    { ISA_FP_ARMv8,ISA_NEON, isa_nobit }
   },
   {
-    "cortex-a57",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
   },
   {
-    "cortex-a72",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "nocrypto", true, false,
+    { ISA_ALL_CRYPTO, isa_nobit }
   },
   {
-    "cortex-a73",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
   },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv8_2_a[] = {
   {
-    "exynos-m1",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "simd", false, false,
+    { ISA_FP_ARMv8,ISA_NEON, isa_nobit }
   },
   {
-    "falkor",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "fp16", false, false,
+    { isa_bit_fp16,ISA_FP_ARMv8,ISA_NEON, isa_nobit }
   },
   {
-    "qdf24xx",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "crypto", false, false,
+    { ISA_FP_ARMv8,ISA_CRYPTO, isa_nobit }
   },
   {
-    "xgene1",
-    {
-      ISA_ARMv8a,
-      isa_nobit
-    },
+    "nocrypto", true, false,
+    { ISA_ALL_CRYPTO, isa_nobit }
   },
   {
-    "cortex-a57.cortex-a53",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
   },
+  { NULL, false, false, {isa_nobit}}
+};
+
+static const struct cpu_arch_extension arch_opttab_armv8_m_main[] = {
   {
-    "cortex-a72.cortex-a53",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "dsp", false, false,
+    { isa_bit_ARMv7em, isa_nobit }
   },
   {
-    "cortex-a73.cortex-a35",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "fp", false, false,
+    { ISA_FPv5, isa_nobit }
   },
   {
-    "cortex-a73.cortex-a53",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "fp.dp", false, false,
+    { ISA_FPv5,ISA_FP_DBL, isa_nobit }
   },
   {
-    "cortex-m23",
-    {
-      ISA_ARMv8m_base,
-      isa_nobit
-    },
+    "nofp", true, false,
+    { ISA_ALL_FP, isa_nobit }
   },
   {
-    "cortex-m33",
-    {
-      ISA_ARMv8m_main,isa_bit_ARMv7em,
-      isa_nobit
-    },
+    "nodsp", true, false,
+    { isa_bit_ARMv7em, isa_nobit }
   },
+  { NULL, false, false, {isa_nobit}}
+};
+
+const arch_option all_architectures[] =
+{
   {
     "armv2",
+    NULL,
     {
       ISA_ARMv2,isa_bit_mode26,
       isa_nobit
     },
+    "2", BASE_ARCH_2,
+    TARGET_CPU_arm2,
   },
   {
     "armv2a",
+    NULL,
     {
       ISA_ARMv2,isa_bit_mode26,
       isa_nobit
     },
+    "2", BASE_ARCH_2,
+    TARGET_CPU_arm2,
   },
   {
     "armv3",
+    NULL,
     {
       ISA_ARMv3,isa_bit_mode26,
       isa_nobit
     },
+    "3", BASE_ARCH_3,
+    TARGET_CPU_arm6,
   },
   {
     "armv3m",
+    NULL,
     {
       ISA_ARMv3m,isa_bit_mode26,
       isa_nobit
     },
+    "3M", BASE_ARCH_3M,
+    TARGET_CPU_arm7m,
   },
   {
     "armv4",
+    NULL,
     {
       ISA_ARMv4,isa_bit_mode26,
       isa_nobit
     },
+    "4", BASE_ARCH_4,
+    TARGET_CPU_arm7tdmi,
   },
   {
     "armv4t",
+    NULL,
     {
       ISA_ARMv4t,
       isa_nobit
     },
+    "4T", BASE_ARCH_4T,
+    TARGET_CPU_arm7tdmi,
   },
   {
     "armv5",
+    NULL,
     {
       ISA_ARMv5,
       isa_nobit
     },
+    "5", BASE_ARCH_5,
+    TARGET_CPU_arm10tdmi,
   },
   {
     "armv5t",
+    NULL,
     {
       ISA_ARMv5t,
       isa_nobit
     },
+    "5T", BASE_ARCH_5T,
+    TARGET_CPU_arm10tdmi,
   },
   {
     "armv5e",
+    arch_opttab_armv5e,
     {
       ISA_ARMv5e,
       isa_nobit
     },
+    "5E", BASE_ARCH_5E,
+    TARGET_CPU_arm1026ejs,
   },
   {
     "armv5te",
+    arch_opttab_armv5te,
     {
       ISA_ARMv5te,
       isa_nobit
     },
+    "5TE", BASE_ARCH_5TE,
+    TARGET_CPU_arm1026ejs,
   },
   {
     "armv5tej",
+    arch_opttab_armv5tej,
     {
       ISA_ARMv5tej,
       isa_nobit
     },
+    "5TEJ", BASE_ARCH_5TEJ,
+    TARGET_CPU_arm1026ejs,
   },
   {
     "armv6",
+    arch_opttab_armv6,
     {
       ISA_ARMv6,
       isa_nobit
     },
+    "6", BASE_ARCH_6,
+    TARGET_CPU_arm1136js,
   },
   {
     "armv6j",
+    arch_opttab_armv6j,
     {
       ISA_ARMv6j,
       isa_nobit
     },
+    "6J", BASE_ARCH_6J,
+    TARGET_CPU_arm1136js,
   },
   {
     "armv6k",
+    arch_opttab_armv6k,
     {
       ISA_ARMv6k,
       isa_nobit
     },
+    "6K", BASE_ARCH_6K,
+    TARGET_CPU_mpcore,
   },
   {
     "armv6z",
+    arch_opttab_armv6z,
     {
       ISA_ARMv6z,
       isa_nobit
     },
+    "6Z", BASE_ARCH_6Z,
+    TARGET_CPU_arm1176jzs,
   },
   {
     "armv6kz",
+    arch_opttab_armv6kz,
     {
       ISA_ARMv6kz,
       isa_nobit
     },
+    "6KZ", BASE_ARCH_6KZ,
+    TARGET_CPU_arm1176jzs,
   },
   {
     "armv6zk",
+    arch_opttab_armv6zk,
     {
       ISA_ARMv6kz,
       isa_nobit
     },
+    "6KZ", BASE_ARCH_6KZ,
+    TARGET_CPU_arm1176jzs,
   },
   {
     "armv6t2",
+    arch_opttab_armv6t2,
     {
       ISA_ARMv6t2,
       isa_nobit
     },
+    "6T2", BASE_ARCH_6T2,
+    TARGET_CPU_arm1156t2s,
   },
   {
     "armv6-m",
+    NULL,
     {
       ISA_ARMv6m,
       isa_nobit
     },
+    "6M", BASE_ARCH_6M,
+    TARGET_CPU_cortexm1,
   },
   {
     "armv6s-m",
+    NULL,
     {
       ISA_ARMv6m,
       isa_nobit
     },
+    "6M", BASE_ARCH_6M,
+    TARGET_CPU_cortexm1,
   },
   {
     "armv7",
+    arch_opttab_armv7,
     {
       ISA_ARMv7,
       isa_nobit
     },
+    "7", BASE_ARCH_7,
+    TARGET_CPU_cortexa8,
   },
   {
     "armv7-a",
+    arch_opttab_armv7_a,
     {
       ISA_ARMv7a,
       isa_nobit
     },
+    "7A", BASE_ARCH_7A,
+    TARGET_CPU_cortexa8,
   },
   {
     "armv7ve",
+    arch_opttab_armv7ve,
     {
       ISA_ARMv7ve,
       isa_nobit
     },
+    "7A", BASE_ARCH_7A,
+    TARGET_CPU_cortexa8,
   },
   {
     "armv7-r",
+    arch_opttab_armv7_r,
     {
       ISA_ARMv7r,
       isa_nobit
     },
+    "7R", BASE_ARCH_7R,
+    TARGET_CPU_cortexr4,
   },
   {
     "armv7-m",
+    NULL,
     {
       ISA_ARMv7m,
       isa_nobit
     },
+    "7M", BASE_ARCH_7M,
+    TARGET_CPU_cortexm3,
   },
   {
     "armv7e-m",
+    arch_opttab_armv7e_m,
     {
       ISA_ARMv7em,
       isa_nobit
     },
+    "7EM", BASE_ARCH_7EM,
+    TARGET_CPU_cortexm4,
   },
   {
     "armv8-a",
+    arch_opttab_armv8_a,
     {
       ISA_ARMv8a,
       isa_nobit
     },
-  },
-  {
-    "armv8-a+crc",
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
+    "8A", BASE_ARCH_8A,
+    TARGET_CPU_cortexa53,
   },
   {
     "armv8.1-a",
+    arch_opttab_armv8_1_a,
     {
       ISA_ARMv8_1a,
       isa_nobit
     },
+    "8A", BASE_ARCH_8A,
+    TARGET_CPU_cortexa53,
   },
   {
     "armv8.2-a",
+    arch_opttab_armv8_2_a,
     {
       ISA_ARMv8_2a,
       isa_nobit
     },
-  },
-  {
-    "armv8.2-a+fp16",
-    {
-      ISA_ARMv8_2a,isa_bit_fp16,
-      isa_nobit
-    },
+    "8A", BASE_ARCH_8A,
+    TARGET_CPU_cortexa53,
   },
   {
     "armv8-m.base",
+    NULL,
     {
       ISA_ARMv8m_base,
       isa_nobit
     },
+    "8M_BASE", BASE_ARCH_8M_BASE,
+    TARGET_CPU_cortexm23,
   },
   {
     "armv8-m.main",
+    arch_opttab_armv8_m_main,
     {
       ISA_ARMv8m_main,
       isa_nobit
     },
-  },
-  {
-    "armv8-m.main+dsp",
-    {
-      ISA_ARMv8m_main,isa_bit_ARMv7em,
-      isa_nobit
-    },
+    "8M_MAIN", BASE_ARCH_8M_MAIN,
+    TARGET_CPU_cortexm7,
   },
   {
     "iwmmxt",
+    NULL,
     {
       ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,
       isa_nobit
     },
+    "5TE", BASE_ARCH_5TE,
+    TARGET_CPU_iwmmxt,
   },
   {
     "iwmmxt2",
+    NULL,
     {
       ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,isa_bit_iwmmxt2,
       isa_nobit
     },
+    "5TE", BASE_ARCH_5TE,
+    TARGET_CPU_iwmmxt2,
   },
+  {{NULL, NULL, {isa_nobit}},
+   NULL, BASE_ARCH_0, TARGET_CPU_arm_none}
 };
 
+const arm_fpu_desc all_fpus[] =
+{
+  {
+    "vfp",
+    {
+      ISA_VFPv2,ISA_FP_DBL,
+      isa_nobit
+    }
+  },
+  {
+    "vfpv2",
+    {
+      ISA_VFPv2,ISA_FP_DBL,
+      isa_nobit
+    }
+  },
+  {
+    "vfpv3",
+    {
+      ISA_VFPv3,ISA_FP_D32,
+      isa_nobit
+    }
+  },
+  {
+    "vfpv3-fp16",
+    {
+      ISA_VFPv3,ISA_FP_D32,isa_bit_fp16conv,
+      isa_nobit
+    }
+  },
+  {
+    "vfpv3-d16",
+    {
+      ISA_VFPv3,ISA_FP_DBL,
+      isa_nobit
+    }
+  },
+  {
+    "vfpv3-d16-fp16",
+    {
+      ISA_VFPv3,ISA_FP_DBL,isa_bit_fp16conv,
+      isa_nobit
+    }
+  },
+  {
+    "vfpv3xd",
+    {
+      ISA_VFPv3,
+      isa_nobit
+    }
+  },
+  {
+    "vfpv3xd-fp16",
+    {
+      ISA_VFPv3,isa_bit_fp16conv,
+      isa_nobit
+    }
+  },
+  {
+    "neon",
+    {
+      ISA_VFPv3,ISA_NEON,
+      isa_nobit
+    }
+  },
+  {
+    "neon-vfpv3",
+    {
+      ISA_VFPv3,ISA_NEON,
+      isa_nobit
+    }
+  },
+  {
+    "neon-fp16",
+    {
+      ISA_VFPv3,ISA_NEON,isa_bit_fp16conv,
+      isa_nobit
+    }
+  },
+  {
+    "vfpv4",
+    {
+      ISA_VFPv4,ISA_FP_D32,
+      isa_nobit
+    }
+  },
+  {
+    "neon-vfpv4",
+    {
+      ISA_VFPv4,ISA_NEON,
+      isa_nobit
+    }
+  },
+  {
+    "vfpv4-d16",
+    {
+      ISA_VFPv4,ISA_FP_DBL,
+      isa_nobit
+    }
+  },
+  {
+    "fpv4-sp-d16",
+    {
+      ISA_VFPv4,
+      isa_nobit
+    }
+  },
+  {
+    "fpv5-sp-d16",
+    {
+      ISA_FPv5,
+      isa_nobit
+    }
+  },
+  {
+    "fpv5-d16",
+    {
+      ISA_FPv5,ISA_FP_DBL,
+      isa_nobit
+    }
+  },
+  {
+    "fp-armv8",
+    {
+      ISA_FP_ARMv8,ISA_FP_D32,
+      isa_nobit
+    }
+  },
+  {
+    "neon-fp-armv8",
+    {
+      ISA_FP_ARMv8,ISA_NEON,
+      isa_nobit
+    }
+  },
+  {
+    "crypto-neon-fp-armv8",
+    {
+      ISA_FP_ARMv8,ISA_CRYPTO,
+      isa_nobit
+    }
+  },
+  {
+    "vfp3",
+    {
+      ISA_VFPv3,ISA_FP_D32,
+      isa_nobit
+    }
+  },
+};
diff --git a/gcc/config/arm/arm-cpu-data.h b/gcc/config/arm/arm-cpu-data.h
index 8d47e7c..c2a18e3 100644
--- a/gcc/config/arm/arm-cpu-data.h
+++ b/gcc/config/arm/arm-cpu-data.h
@@ -20,1743 +20,557 @@
    License along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
-static const struct processors all_cores[] =
+static const cpu_tune all_tunes[] =
 {
-  {
-    "arm2",
+  { /* arm2.  */
     TARGET_CPU_arm2,
     (TF_CO_PROC | TF_NO_MODE32),
-    "2", BASE_ARCH_2,
-    {
-      ISA_ARMv2,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm250",
+  { /* arm250.  */
     TARGET_CPU_arm250,
     (TF_CO_PROC | TF_NO_MODE32),
-    "2", BASE_ARCH_2,
-    {
-      ISA_ARMv2,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm3",
+  { /* arm3.  */
     TARGET_CPU_arm3,
     (TF_CO_PROC | TF_NO_MODE32),
-    "2", BASE_ARCH_2,
-    {
-      ISA_ARMv2,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm6",
+  { /* arm6.  */
     TARGET_CPU_arm6,
     (TF_CO_PROC),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm60",
+  { /* arm60.  */
     TARGET_CPU_arm60,
     (TF_CO_PROC),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm600",
+  { /* arm600.  */
     TARGET_CPU_arm600,
     (TF_CO_PROC | TF_WBUF),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm610",
+  { /* arm610.  */
     TARGET_CPU_arm610,
     (TF_WBUF),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm620",
+  { /* arm620.  */
     TARGET_CPU_arm620,
     (TF_CO_PROC | TF_WBUF),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm7",
+  { /* arm7.  */
     TARGET_CPU_arm7,
     (TF_CO_PROC),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm7d",
+  { /* arm7d.  */
     TARGET_CPU_arm7d,
     (TF_CO_PROC),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm7di",
+  { /* arm7di.  */
     TARGET_CPU_arm7di,
     (TF_CO_PROC),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm70",
+  { /* arm70.  */
     TARGET_CPU_arm70,
     (TF_CO_PROC),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm700",
+  { /* arm700.  */
     TARGET_CPU_arm700,
     (TF_CO_PROC | TF_WBUF),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm700i",
+  { /* arm700i.  */
     TARGET_CPU_arm700i,
     (TF_CO_PROC | TF_WBUF),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm710",
+  { /* arm710.  */
     TARGET_CPU_arm710,
     (TF_WBUF),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm720",
+  { /* arm720.  */
     TARGET_CPU_arm720,
     (TF_WBUF),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm710c",
+  { /* arm710c.  */
     TARGET_CPU_arm710c,
     (TF_WBUF),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm7100",
+  { /* arm7100.  */
     TARGET_CPU_arm7100,
     (TF_WBUF),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm7500",
+  { /* arm7500.  */
     TARGET_CPU_arm7500,
     (TF_WBUF),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm7500fe",
+  { /* arm7500fe.  */
     TARGET_CPU_arm7500fe,
     (TF_CO_PROC | TF_WBUF),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_slowmul_tune
   },
-  {
-    "arm7m",
+  { /* arm7m.  */
     TARGET_CPU_arm7m,
     (TF_CO_PROC),
-    "3M", BASE_ARCH_3M,
-    {
-      ISA_ARMv3m,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm7dm",
+  { /* arm7dm.  */
     TARGET_CPU_arm7dm,
     (TF_CO_PROC),
-    "3M", BASE_ARCH_3M,
-    {
-      ISA_ARMv3m,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm7dmi",
+  { /* arm7dmi.  */
     TARGET_CPU_arm7dmi,
     (TF_CO_PROC),
-    "3M", BASE_ARCH_3M,
-    {
-      ISA_ARMv3m,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm8",
+  { /* arm8.  */
     TARGET_CPU_arm8,
     (TF_LDSCHED),
-    "4", BASE_ARCH_4,
-    {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm810",
+  { /* arm810.  */
     TARGET_CPU_arm810,
     (TF_LDSCHED),
-    "4", BASE_ARCH_4,
-    {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "strongarm",
+  { /* strongarm.  */
     TARGET_CPU_strongarm,
     (TF_LDSCHED | TF_STRONG),
-    "4", BASE_ARCH_4,
-    {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_strongarm_tune
   },
-  {
-    "strongarm110",
+  { /* strongarm110.  */
     TARGET_CPU_strongarm110,
     (TF_LDSCHED | TF_STRONG),
-    "4", BASE_ARCH_4,
-    {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_strongarm_tune
   },
-  {
-    "strongarm1100",
+  { /* strongarm1100.  */
     TARGET_CPU_strongarm1100,
     (TF_LDSCHED | TF_STRONG),
-    "4", BASE_ARCH_4,
-    {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_strongarm_tune
   },
-  {
-    "strongarm1110",
+  { /* strongarm1110.  */
     TARGET_CPU_strongarm1110,
     (TF_LDSCHED | TF_STRONG),
-    "4", BASE_ARCH_4,
-    {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_strongarm_tune
   },
-  {
-    "fa526",
+  { /* fa526.  */
     TARGET_CPU_fa526,
     (TF_LDSCHED),
-    "4", BASE_ARCH_4,
-    {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "fa626",
+  { /* fa626.  */
     TARGET_CPU_fa626,
     (TF_LDSCHED),
-    "4", BASE_ARCH_4,
-    {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm7tdmi",
+  { /* arm7tdmi.  */
     TARGET_CPU_arm7tdmi,
     (TF_CO_PROC),
-    "4T", BASE_ARCH_4T,
-    {
-      ISA_ARMv4t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm7tdmi-s",
+  { /* arm7tdmi-s.  */
     TARGET_CPU_arm7tdmis,
     (TF_CO_PROC),
-    "4T", BASE_ARCH_4T,
-    {
-      ISA_ARMv4t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm710t",
+  { /* arm710t.  */
     TARGET_CPU_arm710t,
     (TF_WBUF),
-    "4T", BASE_ARCH_4T,
-    {
-      ISA_ARMv4t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm720t",
+  { /* arm720t.  */
     TARGET_CPU_arm720t,
     (TF_WBUF),
-    "4T", BASE_ARCH_4T,
-    {
-      ISA_ARMv4t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm740t",
+  { /* arm740t.  */
     TARGET_CPU_arm740t,
     (TF_WBUF),
-    "4T", BASE_ARCH_4T,
-    {
-      ISA_ARMv4t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm9",
+  { /* arm9.  */
     TARGET_CPU_arm9,
     (TF_LDSCHED),
-    "4T", BASE_ARCH_4T,
-    {
-      ISA_ARMv4t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm9tdmi",
+  { /* arm9tdmi.  */
     TARGET_CPU_arm9tdmi,
     (TF_LDSCHED),
-    "4T", BASE_ARCH_4T,
-    {
-      ISA_ARMv4t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm920",
+  { /* arm920.  */
     TARGET_CPU_arm920,
     (TF_LDSCHED),
-    "4T", BASE_ARCH_4T,
-    {
-      ISA_ARMv4t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm920t",
+  { /* arm920t.  */
     TARGET_CPU_arm920t,
     (TF_LDSCHED),
-    "4T", BASE_ARCH_4T,
-    {
-      ISA_ARMv4t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm922t",
+  { /* arm922t.  */
     TARGET_CPU_arm922t,
     (TF_LDSCHED),
-    "4T", BASE_ARCH_4T,
-    {
-      ISA_ARMv4t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm940t",
+  { /* arm940t.  */
     TARGET_CPU_arm940t,
     (TF_LDSCHED),
-    "4T", BASE_ARCH_4T,
-    {
-      ISA_ARMv4t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "ep9312",
+  { /* ep9312.  */
     TARGET_CPU_ep9312,
     (TF_LDSCHED),
-    "4T", BASE_ARCH_4T,
-    {
-      ISA_ARMv4t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm10tdmi",
+  { /* arm10tdmi.  */
     TARGET_CPU_arm10tdmi,
     (TF_LDSCHED),
-    "5T", BASE_ARCH_5T,
-    {
-      ISA_ARMv5t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm1020t",
+  { /* arm1020t.  */
     TARGET_CPU_arm1020t,
     (TF_LDSCHED),
-    "5T", BASE_ARCH_5T,
-    {
-      ISA_ARMv5t,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm9e",
+  { /* arm9e.  */
     TARGET_CPU_arm9e,
     (TF_LDSCHED),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "arm946e-s",
+  { /* arm946e-s.  */
     TARGET_CPU_arm946es,
     (TF_LDSCHED),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "arm966e-s",
+  { /* arm966e-s.  */
     TARGET_CPU_arm966es,
     (TF_LDSCHED),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "arm968e-s",
+  { /* arm968e-s.  */
     TARGET_CPU_arm968es,
     (TF_LDSCHED),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "arm10e",
+  { /* arm10e.  */
     TARGET_CPU_arm10e,
     (TF_LDSCHED),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm1020e",
+  { /* arm1020e.  */
     TARGET_CPU_arm1020e,
     (TF_LDSCHED),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "arm1022e",
+  { /* arm1022e.  */
     TARGET_CPU_arm1022e,
     (TF_LDSCHED),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,
-      isa_nobit
-    },
     &arm_fastmul_tune
   },
-  {
-    "xscale",
+  { /* xscale.  */
     TARGET_CPU_xscale,
     (TF_LDSCHED | TF_XSCALE),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,
-      isa_bit_xscale,
-      isa_nobit
-    },
     &arm_xscale_tune
   },
-  {
-    "iwmmxt",
+  { /* iwmmxt.  */
     TARGET_CPU_iwmmxt,
     (TF_LDSCHED | TF_XSCALE),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,
-      isa_nobit
-    },
     &arm_xscale_tune
   },
-  {
-    "iwmmxt2",
+  { /* iwmmxt2.  */
     TARGET_CPU_iwmmxt2,
     (TF_LDSCHED | TF_XSCALE),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,isa_bit_iwmmxt2,
-      isa_nobit
-    },
     &arm_xscale_tune
   },
-  {
-    "fa606te",
+  { /* fa606te.  */
     TARGET_CPU_fa606te,
     (TF_LDSCHED),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "fa626te",
+  { /* fa626te.  */
     TARGET_CPU_fa626te,
     (TF_LDSCHED),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "fmp626",
+  { /* fmp626.  */
     TARGET_CPU_fmp626,
     (TF_LDSCHED),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "fa726te",
+  { /* fa726te.  */
     TARGET_CPU_fa726te,
     (TF_LDSCHED),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,
-      isa_nobit
-    },
     &arm_fa726te_tune
   },
-  {
-    "arm926ej-s",
+  { /* arm926ej-s.  */
     TARGET_CPU_arm926ejs,
     (TF_LDSCHED),
-    "5TEJ", BASE_ARCH_5TEJ,
-    {
-      ISA_ARMv5tej,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "arm1026ej-s",
+  { /* arm1026ej-s.  */
     TARGET_CPU_arm1026ejs,
     (TF_LDSCHED),
-    "5TEJ", BASE_ARCH_5TEJ,
-    {
-      ISA_ARMv5tej,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "arm1136j-s",
+  { /* arm1136j-s.  */
     TARGET_CPU_arm1136js,
     (TF_LDSCHED),
-    "6J", BASE_ARCH_6J,
-    {
-      ISA_ARMv6j,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "arm1136jf-s",
+  { /* arm1136jf-s.  */
     TARGET_CPU_arm1136jfs,
     (TF_LDSCHED),
-    "6J", BASE_ARCH_6J,
-    {
-      ISA_ARMv6j,
-      ISA_VFPv2,ISA_FP_DBL,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "arm1176jz-s",
+  { /* arm1176jz-s.  */
     TARGET_CPU_arm1176jzs,
     (TF_LDSCHED),
-    "6KZ", BASE_ARCH_6KZ,
-    {
-      ISA_ARMv6kz,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "arm1176jzf-s",
+  { /* arm1176jzf-s.  */
     TARGET_CPU_arm1176jzfs,
     (TF_LDSCHED),
-    "6KZ", BASE_ARCH_6KZ,
-    {
-      ISA_ARMv6kz,
-      ISA_VFPv2,ISA_FP_DBL,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "mpcorenovfp",
+  { /* mpcorenovfp.  */
     TARGET_CPU_mpcorenovfp,
     (TF_LDSCHED),
-    "6K", BASE_ARCH_6K,
-    {
-      ISA_ARMv6k,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "mpcore",
+  { /* mpcore.  */
     TARGET_CPU_mpcore,
     (TF_LDSCHED),
-    "6K", BASE_ARCH_6K,
-    {
-      ISA_ARMv6k,
-      ISA_VFPv2,ISA_FP_DBL,
-      isa_nobit
-    },
     &arm_9e_tune
   },
-  {
-    "arm1156t2-s",
+  { /* arm1156t2-s.  */
     TARGET_CPU_arm1156t2s,
     (TF_LDSCHED),
-    "6T2", BASE_ARCH_6T2,
-    {
-      ISA_ARMv6t2,
-      isa_nobit
-    },
     &arm_v6t2_tune
   },
-  {
-    "arm1156t2f-s",
+  { /* arm1156t2f-s.  */
     TARGET_CPU_arm1156t2fs,
     (TF_LDSCHED),
-    "6T2", BASE_ARCH_6T2,
-    {
-      ISA_ARMv6t2,
-      ISA_VFPv2,ISA_FP_DBL,
-      isa_nobit
-    },
     &arm_v6t2_tune
   },
-  {
-    "cortex-m1",
+  { /* cortex-m1.  */
     TARGET_CPU_cortexm1,
     (TF_LDSCHED),
-    "6M", BASE_ARCH_6M,
-    {
-      ISA_ARMv6m,
-      isa_nobit
-    },
     &arm_v6m_tune
   },
-  {
-    "cortex-m0",
+  { /* cortex-m0.  */
     TARGET_CPU_cortexm0,
     (TF_LDSCHED),
-    "6M", BASE_ARCH_6M,
-    {
-      ISA_ARMv6m,
-      isa_nobit
-    },
     &arm_v6m_tune
   },
-  {
-    "cortex-m0plus",
+  { /* cortex-m0plus.  */
     TARGET_CPU_cortexm0plus,
     (TF_LDSCHED),
-    "6M", BASE_ARCH_6M,
-    {
-      ISA_ARMv6m,
-      isa_nobit
-    },
     &arm_v6m_tune
   },
-  {
-    "cortex-m1.small-multiply",
+  { /* cortex-m1.small-multiply.  */
     TARGET_CPU_cortexm1,
     (TF_LDSCHED | TF_SMALLMUL),
-    "6M", BASE_ARCH_6M,
-    {
-      ISA_ARMv6m,
-      isa_nobit
-    },
     &arm_v6m_tune
   },
-  {
-    "cortex-m0.small-multiply",
+  { /* cortex-m0.small-multiply.  */
     TARGET_CPU_cortexm0,
     (TF_LDSCHED | TF_SMALLMUL),
-    "6M", BASE_ARCH_6M,
-    {
-      ISA_ARMv6m,
-      isa_nobit
-    },
     &arm_v6m_tune
   },
-  {
-    "cortex-m0plus.small-multiply",
+  { /* cortex-m0plus.small-multiply.  */
     TARGET_CPU_cortexm0plus,
     (TF_LDSCHED | TF_SMALLMUL),
-    "6M", BASE_ARCH_6M,
-    {
-      ISA_ARMv6m,
-      isa_nobit
-    },
     &arm_v6m_tune
   },
-  {
-    "generic-armv7-a",
+  { /* generic-armv7-a.  */
     TARGET_CPU_genericv7a,
     (TF_LDSCHED),
-    "7A", BASE_ARCH_7A,
-    {
-      ISA_ARMv7a,
-      isa_nobit
-    },
     &arm_cortex_tune
   },
-  {
-    "cortex-a5",
+  { /* cortex-a5.  */
     TARGET_CPU_cortexa5,
     (TF_LDSCHED),
-    "7A", BASE_ARCH_7A,
-    {
-      ISA_ARMv7a,
-      isa_nobit
-    },
     &arm_cortex_a5_tune
   },
-  {
-    "cortex-a7",
+  { /* cortex-a7.  */
     TARGET_CPU_cortexa7,
     (TF_LDSCHED),
-    "7A", BASE_ARCH_7A,
-    {
-      ISA_ARMv7ve,
-      isa_nobit
-    },
     &arm_cortex_a7_tune
   },
-  {
-    "cortex-a8",
+  { /* cortex-a8.  */
     TARGET_CPU_cortexa8,
     (TF_LDSCHED),
-    "7A", BASE_ARCH_7A,
-    {
-      ISA_ARMv7a,
-      isa_nobit
-    },
     &arm_cortex_a8_tune
   },
-  {
-    "cortex-a9",
+  { /* cortex-a9.  */
     TARGET_CPU_cortexa9,
     (TF_LDSCHED),
-    "7A", BASE_ARCH_7A,
-    {
-      ISA_ARMv7a,
-      isa_nobit
-    },
     &arm_cortex_a9_tune
   },
-  {
-    "cortex-a12",
+  { /* cortex-a12.  */
     TARGET_CPU_cortexa17,
     (TF_LDSCHED),
-    "7A", BASE_ARCH_7A,
-    {
-      ISA_ARMv7ve,
-      isa_nobit
-    },
     &arm_cortex_a12_tune
   },
-  {
-    "cortex-a15",
+  { /* cortex-a15.  */
     TARGET_CPU_cortexa15,
     (TF_LDSCHED),
-    "7A", BASE_ARCH_7A,
-    {
-      ISA_ARMv7ve,
-      isa_nobit
-    },
     &arm_cortex_a15_tune
   },
-  {
-    "cortex-a17",
+  { /* cortex-a17.  */
     TARGET_CPU_cortexa17,
     (TF_LDSCHED),
-    "7A", BASE_ARCH_7A,
-    {
-      ISA_ARMv7ve,
-      isa_nobit
-    },
     &arm_cortex_a12_tune
   },
-  {
-    "cortex-r4",
+  { /* cortex-r4.  */
     TARGET_CPU_cortexr4,
     (TF_LDSCHED),
-    "7R", BASE_ARCH_7R,
-    {
-      ISA_ARMv7r,
-      isa_nobit
-    },
     &arm_cortex_tune
   },
-  {
-    "cortex-r4f",
+  { /* cortex-r4f.  */
     TARGET_CPU_cortexr4f,
     (TF_LDSCHED),
-    "7R", BASE_ARCH_7R,
-    {
-      ISA_ARMv7r,
-      isa_nobit
-    },
     &arm_cortex_tune
   },
-  {
-    "cortex-r5",
+  { /* cortex-r5.  */
     TARGET_CPU_cortexr5,
     (TF_LDSCHED),
-    "7R", BASE_ARCH_7R,
-    {
-      ISA_ARMv7r,
-      isa_bit_adiv,
-      isa_nobit
-    },
     &arm_cortex_tune
   },
-  {
-    "cortex-r7",
+  { /* cortex-r7.  */
     TARGET_CPU_cortexr7,
     (TF_LDSCHED),
-    "7R", BASE_ARCH_7R,
-    {
-      ISA_ARMv7r,
-      isa_bit_adiv,
-      isa_nobit
-    },
     &arm_cortex_tune
   },
-  {
-    "cortex-r8",
+  { /* cortex-r8.  */
     TARGET_CPU_cortexr7,
     (TF_LDSCHED),
-    "7R", BASE_ARCH_7R,
-    {
-      ISA_ARMv7r,
-      isa_bit_adiv,
-      isa_nobit
-    },
     &arm_cortex_tune
   },
-  {
-    "cortex-m7",
+  { /* cortex-m7.  */
     TARGET_CPU_cortexm7,
     (TF_LDSCHED),
-    "7EM", BASE_ARCH_7EM,
-    {
-      ISA_ARMv7em,
-      isa_quirk_no_volatile_ce,
-      isa_nobit
-    },
     &arm_cortex_m7_tune
   },
-  {
-    "cortex-m4",
+  { /* cortex-m4.  */
     TARGET_CPU_cortexm4,
     (TF_LDSCHED),
-    "7EM", BASE_ARCH_7EM,
-    {
-      ISA_ARMv7em,
-      isa_nobit
-    },
     &arm_v7m_tune
   },
-  {
-    "cortex-m3",
+  { /* cortex-m3.  */
     TARGET_CPU_cortexm3,
     (TF_LDSCHED),
-    "7M", BASE_ARCH_7M,
-    {
-      ISA_ARMv7m,
-      isa_quirk_cm3_ldrd,
-      isa_nobit
-    },
     &arm_v7m_tune
   },
-  {
-    "marvell-pj4",
+  { /* marvell-pj4.  */
     TARGET_CPU_marvell_pj4,
     (TF_LDSCHED),
-    "7A", BASE_ARCH_7A,
-    {
-      ISA_ARMv7a,
-      isa_nobit
-    },
     &arm_marvell_pj4_tune
   },
-  {
-    "cortex-a15.cortex-a7",
+  { /* cortex-a15.cortex-a7.  */
     TARGET_CPU_cortexa7,
     (TF_LDSCHED),
-    "7A", BASE_ARCH_7A,
-    {
-      ISA_ARMv7ve,
-      isa_nobit
-    },
     &arm_cortex_a15_tune
   },
-  {
-    "cortex-a17.cortex-a7",
+  { /* cortex-a17.cortex-a7.  */
     TARGET_CPU_cortexa7,
     (TF_LDSCHED),
-    "7A", BASE_ARCH_7A,
-    {
-      ISA_ARMv7ve,
-      isa_nobit
-    },
     &arm_cortex_a12_tune
   },
-  {
-    "cortex-a32",
+  { /* cortex-a32.  */
     TARGET_CPU_cortexa53,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
     &arm_cortex_a35_tune
   },
-  {
-    "cortex-a35",
+  { /* cortex-a35.  */
     TARGET_CPU_cortexa53,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
     &arm_cortex_a35_tune
   },
-  {
-    "cortex-a53",
+  { /* cortex-a53.  */
     TARGET_CPU_cortexa53,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
     &arm_cortex_a53_tune
   },
-  {
-    "cortex-a57",
+  { /* cortex-a57.  */
     TARGET_CPU_cortexa57,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
     &arm_cortex_a57_tune
   },
-  {
-    "cortex-a72",
+  { /* cortex-a72.  */
     TARGET_CPU_cortexa57,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
     &arm_cortex_a57_tune
   },
-  {
-    "cortex-a73",
+  { /* cortex-a73.  */
     TARGET_CPU_cortexa57,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
     &arm_cortex_a73_tune
   },
-  {
-    "exynos-m1",
+  { /* exynos-m1.  */
     TARGET_CPU_exynosm1,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
     &arm_exynosm1_tune
   },
-  {
-    "falkor",
+  { /* falkor.  */
     TARGET_CPU_cortexa57,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
     &arm_qdf24xx_tune
   },
-  {
-    "qdf24xx",
+  { /* qdf24xx.  */
     TARGET_CPU_cortexa57,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
     &arm_qdf24xx_tune
   },
-  {
-    "xgene1",
+  { /* xgene1.  */
     TARGET_CPU_xgene1,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,
-      isa_nobit
-    },
     &arm_xgene1_tune
   },
-  {
-    "cortex-a57.cortex-a53",
+  { /* cortex-a57.cortex-a53.  */
     TARGET_CPU_cortexa53,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
     &arm_cortex_a57_tune
   },
-  {
-    "cortex-a72.cortex-a53",
+  { /* cortex-a72.cortex-a53.  */
     TARGET_CPU_cortexa53,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
     &arm_cortex_a57_tune
   },
-  {
-    "cortex-a73.cortex-a35",
+  { /* cortex-a73.cortex-a35.  */
     TARGET_CPU_cortexa53,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
     &arm_cortex_a73_tune
   },
-  {
-    "cortex-a73.cortex-a53",
+  { /* cortex-a73.cortex-a53.  */
     TARGET_CPU_cortexa53,
     (TF_LDSCHED),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8a,isa_bit_crc32,
-      isa_nobit
-    },
     &arm_cortex_a73_tune
   },
-  {
-    "cortex-m23",
+  { /* cortex-m23.  */
     TARGET_CPU_cortexm23,
     (TF_LDSCHED),
-    "8M_BASE", BASE_ARCH_8M_BASE,
-    {
-      ISA_ARMv8m_base,
-      isa_nobit
-    },
     &arm_v6m_tune
   },
-  {
-    "cortex-m33",
+  { /* cortex-m33.  */
     TARGET_CPU_cortexm33,
     (TF_LDSCHED),
-    "8M_MAIN", BASE_ARCH_8M_MAIN,
-    {
-      ISA_ARMv8m_main,isa_bit_ARMv7em,
-      isa_nobit
-    },
     &arm_v7m_tune
   },
-  {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0, {isa_nobit}, NULL}
-};
-
-static const struct processors all_architectures[] =
-{
-  {
-    "armv2", TARGET_CPU_arm2,
-    (TF_CO_PROC | TF_NO_MODE32),
-    "2", BASE_ARCH_2,
-    {
-      ISA_ARMv2,isa_bit_mode26,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv2a", TARGET_CPU_arm2,
-    (TF_CO_PROC | TF_NO_MODE32),
-    "2", BASE_ARCH_2,
-    {
-      ISA_ARMv2,isa_bit_mode26,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv3", TARGET_CPU_arm6,
-    (TF_CO_PROC),
-    "3", BASE_ARCH_3,
-    {
-      ISA_ARMv3,isa_bit_mode26,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv3m", TARGET_CPU_arm7m,
-    (TF_CO_PROC),
-    "3M", BASE_ARCH_3M,
-    {
-      ISA_ARMv3m,isa_bit_mode26,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv4", TARGET_CPU_arm7tdmi,
-    (TF_CO_PROC),
-    "4", BASE_ARCH_4,
-    {
-      ISA_ARMv4,isa_bit_mode26,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv4t", TARGET_CPU_arm7tdmi,
-    (TF_CO_PROC),
-    "4T", BASE_ARCH_4T,
-    {
-      ISA_ARMv4t,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv5", TARGET_CPU_arm10tdmi,
-    (TF_CO_PROC),
-    "5", BASE_ARCH_5,
-    {
-      ISA_ARMv5,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv5t", TARGET_CPU_arm10tdmi,
-    (TF_CO_PROC),
-    "5T", BASE_ARCH_5T,
-    {
-      ISA_ARMv5t,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv5e", TARGET_CPU_arm1026ejs,
-    (TF_CO_PROC),
-    "5E", BASE_ARCH_5E,
-    {
-      ISA_ARMv5e,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv5te", TARGET_CPU_arm1026ejs,
-    (TF_CO_PROC),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv5tej", TARGET_CPU_arm1026ejs,
-    (TF_CO_PROC),
-    "5TEJ", BASE_ARCH_5TEJ,
-    {
-      ISA_ARMv5tej,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv6", TARGET_CPU_arm1136js,
-    (TF_CO_PROC),
-    "6", BASE_ARCH_6,
-    {
-      ISA_ARMv6,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv6j", TARGET_CPU_arm1136js,
-    (TF_CO_PROC),
-    "6J", BASE_ARCH_6J,
-    {
-      ISA_ARMv6j,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv6k", TARGET_CPU_mpcore,
-    (TF_CO_PROC),
-    "6K", BASE_ARCH_6K,
-    {
-      ISA_ARMv6k,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv6z", TARGET_CPU_arm1176jzs,
-    (TF_CO_PROC),
-    "6Z", BASE_ARCH_6Z,
-    {
-      ISA_ARMv6z,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv6kz", TARGET_CPU_arm1176jzs,
-    (TF_CO_PROC),
-    "6KZ", BASE_ARCH_6KZ,
-    {
-      ISA_ARMv6kz,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv6zk", TARGET_CPU_arm1176jzs,
-    (TF_CO_PROC),
-    "6KZ", BASE_ARCH_6KZ,
-    {
-      ISA_ARMv6kz,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv6t2", TARGET_CPU_arm1156t2s,
-    (TF_CO_PROC),
-    "6T2", BASE_ARCH_6T2,
-    {
-      ISA_ARMv6t2,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv6-m", TARGET_CPU_cortexm1,
-    0,
-    "6M", BASE_ARCH_6M,
-    {
-      ISA_ARMv6m,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv6s-m", TARGET_CPU_cortexm1,
-    0,
-    "6M", BASE_ARCH_6M,
-    {
-      ISA_ARMv6m,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv7", TARGET_CPU_cortexa8,
-    (TF_CO_PROC),
-    "7", BASE_ARCH_7,
-    {
-      ISA_ARMv7,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv7-a", TARGET_CPU_cortexa8,
-    (TF_CO_PROC),
-    "7A", BASE_ARCH_7A,
-    {
-      ISA_ARMv7a,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv7ve", TARGET_CPU_cortexa8,
-    (TF_CO_PROC),
-    "7A", BASE_ARCH_7A,
-    {
-      ISA_ARMv7ve,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv7-r", TARGET_CPU_cortexr4,
-    (TF_CO_PROC),
-    "7R", BASE_ARCH_7R,
-    {
-      ISA_ARMv7r,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv7-m", TARGET_CPU_cortexm3,
-    (TF_CO_PROC),
-    "7M", BASE_ARCH_7M,
-    {
-      ISA_ARMv7m,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv7e-m", TARGET_CPU_cortexm4,
-    (TF_CO_PROC),
-    "7EM", BASE_ARCH_7EM,
-    {
-      ISA_ARMv7em,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv8-a", TARGET_CPU_cortexa53,
-    (TF_CO_PROC),
-    "8A", BASE_ARCH_8A,
-    {
-      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
-    },
-    NULL
-  },
-  {
-    "armv8.1-a", TARGET_CPU_cortexa53,
-    (TF_CO_PROC),
-    "8A", BASE_ARCH_8A,
-    {
-      ISA_ARMv8_1a,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv8.2-a", TARGET_CPU_cortexa53,
-    (TF_CO_PROC),
-    "8A", BASE_ARCH_8A,
-    {
-      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
-    },
-    NULL
-  },
-  {
-    "armv8-m.base", TARGET_CPU_cortexm23,
-    0,
-    "8M_BASE", BASE_ARCH_8M_BASE,
-    {
-      ISA_ARMv8m_base,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "armv8-m.main", TARGET_CPU_cortexm7,
-    (TF_CO_PROC),
-    "8M_MAIN", BASE_ARCH_8M_MAIN,
-    {
-      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
-    },
-    NULL
-  },
-  {
-    "iwmmxt", TARGET_CPU_iwmmxt,
-    (TF_LDSCHED | TF_STRONG | TF_XSCALE),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,
-      isa_nobit
-    },
-    NULL
-  },
-  {
-    "iwmmxt2", TARGET_CPU_iwmmxt2,
-    (TF_LDSCHED | TF_STRONG | TF_XSCALE),
-    "5TE", BASE_ARCH_5TE,
-    {
-      ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,isa_bit_iwmmxt2,
-      isa_nobit
-    },
-    NULL
-  },
-  {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0, {isa_nobit}, NULL}
-};
-
-const struct arm_fpu_desc all_fpus[] =
-{
-  {
-    "vfp",
-    {
-      ISA_VFPv2,ISA_FP_DBL,
-      isa_nobit
-    }
-  },
-  {
-    "vfpv2",
-    {
-      ISA_VFPv2,ISA_FP_DBL,
-      isa_nobit
-    }
-  },
-  {
-    "vfpv3",
-    {
-      ISA_VFPv3,ISA_FP_D32,
-      isa_nobit
-    }
-  },
-  {
-    "vfpv3-fp16",
-    {
-      ISA_VFPv3,ISA_FP_D32,isa_bit_fp16conv,
-      isa_nobit
-    }
-  },
-  {
-    "vfpv3-d16",
-    {
-      ISA_VFPv3,ISA_FP_DBL,
-      isa_nobit
-    }
-  },
-  {
-    "vfpv3-d16-fp16",
-    {
-      ISA_VFPv3,ISA_FP_DBL,isa_bit_fp16conv,
-      isa_nobit
-    }
-  },
-  {
-    "vfpv3xd",
-    {
-      ISA_VFPv3,
-      isa_nobit
-    }
-  },
-  {
-    "vfpv3xd-fp16",
-    {
-      ISA_VFPv3,isa_bit_fp16conv,
-      isa_nobit
-    }
-  },
-  {
-    "neon",
-    {
-      ISA_VFPv3,ISA_NEON,
-      isa_nobit
-    }
-  },
-  {
-    "neon-vfpv3",
-    {
-      ISA_VFPv3,ISA_NEON,
-      isa_nobit
-    }
-  },
-  {
-    "neon-fp16",
-    {
-      ISA_VFPv3,ISA_NEON,isa_bit_fp16conv,
-      isa_nobit
-    }
-  },
-  {
-    "vfpv4",
-    {
-      ISA_VFPv4,ISA_FP_D32,
-      isa_nobit
-    }
-  },
-  {
-    "neon-vfpv4",
-    {
-      ISA_VFPv4,ISA_NEON,
-      isa_nobit
-    }
-  },
-  {
-    "vfpv4-d16",
-    {
-      ISA_VFPv4,ISA_FP_DBL,
-      isa_nobit
-    }
-  },
-  {
-    "fpv4-sp-d16",
-    {
-      ISA_VFPv4,
-      isa_nobit
-    }
-  },
-  {
-    "fpv5-sp-d16",
-    {
-      ISA_FPv5,
-      isa_nobit
-    }
-  },
-  {
-    "fpv5-d16",
-    {
-      ISA_FPv5,ISA_FP_DBL,
-      isa_nobit
-    }
-  },
-  {
-    "fp-armv8",
-    {
-      ISA_FP_ARMv8,ISA_FP_D32,
-      isa_nobit
-    }
-  },
-  {
-    "neon-fp-armv8",
-    {
-      ISA_FP_ARMv8,ISA_NEON,
-      isa_nobit
-    }
-  },
-  {
-    "crypto-neon-fp-armv8",
-    {
-      ISA_FP_ARMv8,ISA_CRYPTO,
-      isa_nobit
-    }
-  },
-  {
-    "vfp3",
-    {
-      ISA_VFPv3,ISA_FP_D32,
-      isa_nobit
-    }
-  },
+  {TARGET_CPU_arm_none, 0, NULL}
 };
diff --git a/gcc/config/arm/arm-cpu.h b/gcc/config/arm/arm-cpu.h
index cd282db..d36ccb9 100644
--- a/gcc/config/arm/arm-cpu.h
+++ b/gcc/config/arm/arm-cpu.h
@@ -135,6 +135,44 @@ enum processor_type
   TARGET_CPU_arm_none
 };
 
+enum arch_type
+{
+  TARGET_ARCH_armv2,
+  TARGET_ARCH_armv2a,
+  TARGET_ARCH_armv3,
+  TARGET_ARCH_armv3m,
+  TARGET_ARCH_armv4,
+  TARGET_ARCH_armv4t,
+  TARGET_ARCH_armv5,
+  TARGET_ARCH_armv5t,
+  TARGET_ARCH_armv5e,
+  TARGET_ARCH_armv5te,
+  TARGET_ARCH_armv5tej,
+  TARGET_ARCH_armv6,
+  TARGET_ARCH_armv6j,
+  TARGET_ARCH_armv6k,
+  TARGET_ARCH_armv6z,
+  TARGET_ARCH_armv6kz,
+  TARGET_ARCH_armv6zk,
+  TARGET_ARCH_armv6t2,
+  TARGET_ARCH_armv6_m,
+  TARGET_ARCH_armv6s_m,
+  TARGET_ARCH_armv7,
+  TARGET_ARCH_armv7_a,
+  TARGET_ARCH_armv7ve,
+  TARGET_ARCH_armv7_r,
+  TARGET_ARCH_armv7_m,
+  TARGET_ARCH_armv7e_m,
+  TARGET_ARCH_armv8_a,
+  TARGET_ARCH_armv8_1_a,
+  TARGET_ARCH_armv8_2_a,
+  TARGET_ARCH_armv8_m_base,
+  TARGET_ARCH_armv8_m_main,
+  TARGET_ARCH_iwmmxt,
+  TARGET_ARCH_iwmmxt2,
+  TARGET_ARCH_arm_none
+};
+
 enum fpu_type
 {
   TARGET_FPU_vfp,
diff --git a/gcc/config/arm/arm-cpus.in b/gcc/config/arm/arm-cpus.in
index d116b09..b0c0eae 100644
--- a/gcc/config/arm/arm-cpus.in
+++ b/gcc/config/arm/arm-cpus.in
@@ -113,6 +113,9 @@ begin arch armv5e
  tune flags CO_PROC
  base 5E
  isa ARMv5e
+ option fp add VFPv2 FP_DBL
+ optalias vfpv2 fp
+ option nofp remove ALL_FP
 end arch armv5e
 
 begin arch armv5te
@@ -120,6 +123,9 @@ begin arch armv5te
  tune flags CO_PROC
  base 5TE
  isa ARMv5te
+ option fp add VFPv2 FP_DBL
+ optalias vfpv2 fp
+ option nofp remove ALL_FP
 end arch armv5te
 
 begin arch armv5tej
@@ -127,6 +133,9 @@ begin arch armv5tej
  tune flags CO_PROC
  base 5TEJ
  isa ARMv5tej
+ option fp add VFPv2 FP_DBL
+ optalias vfpv2 fp
+ option nofp remove ALL_FP
 end arch armv5tej
 
 begin arch armv6
@@ -134,6 +143,9 @@ begin arch armv6
  tune flags CO_PROC
  base 6
  isa ARMv6
+ option fp add VFPv2 FP_DBL
+ optalias vfpv2 fp
+ option nofp remove ALL_FP
 end arch armv6
 
 begin arch armv6j
@@ -141,6 +153,9 @@ begin arch armv6j
  tune flags CO_PROC
  base 6J
  isa ARMv6j
+ option fp add VFPv2 FP_DBL
+ optalias vfpv2 fp
+ option nofp remove ALL_FP
 end arch armv6j
 
 begin arch armv6k
@@ -148,6 +163,9 @@ begin arch armv6k
  tune flags CO_PROC
  base 6K
  isa ARMv6k
+ option fp add VFPv2 FP_DBL
+ optalias vfpv2 fp
+ option nofp remove ALL_FP
 end arch armv6k
 
 begin arch armv6z
@@ -155,6 +173,9 @@ begin arch armv6z
  tune flags CO_PROC
  base 6Z
  isa ARMv6z
+ option fp add VFPv2 FP_DBL
+ optalias vfpv2 fp
+ option nofp remove ALL_FP
 end arch armv6z
 
 begin arch armv6kz
@@ -162,6 +183,9 @@ begin arch armv6kz
  tune flags CO_PROC
  base 6KZ
  isa ARMv6kz
+ option fp add VFPv2 FP_DBL
+ optalias vfpv2 fp
+ option nofp remove ALL_FP
 end arch armv6kz
 
 begin arch armv6zk
@@ -169,6 +193,9 @@ begin arch armv6zk
  tune flags CO_PROC
  base 6KZ
  isa ARMv6kz
+ option fp add VFPv2 FP_DBL
+ optalias vfpv2 fp
+ option nofp remove ALL_FP
 end arch armv6zk
 
 begin arch armv6t2
@@ -176,6 +203,9 @@ begin arch armv6t2
  tune flags CO_PROC
  base 6T2
  isa ARMv6t2
+ option fp add VFPv2 FP_DBL
+ optalias vfpv2 fp
+ option nofp remove ALL_FP
 end arch armv6t2
 
 begin arch armv6-m
@@ -195,6 +225,10 @@ begin arch armv7
  tune flags CO_PROC
  base 7
  isa ARMv7
+# fp => VFPv3-d16 (only useful for the A+R profile subset).
+ option fp add VFPv3 FP_DBL
+ optalias vfpv3-d16 fp
+ option nofp remove ALL_FP
 end arch armv7
 
 begin arch armv7-a
@@ -202,6 +236,21 @@ begin arch armv7-a
  tune flags CO_PROC
  base 7A
  isa ARMv7a
+# fp => VFPv3-d16, simd => neon-vfpv3
+ 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 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-vfpv4     add VFPv4 NEON
+ option nosimd	    remove ALL_SIMD
+ option nofp	    remove ALL_FP
 end arch armv7-a
 
 begin arch armv7ve
@@ -209,6 +258,21 @@ begin arch armv7ve
  tune flags CO_PROC
  base 7A
  isa 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 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 simd 	       add VFPv4 NEON
+ optalias neon-vfpv4   simd
+ option nosimd	    remove ALL_SIMD
+ option nofp	    remove ALL_FP
 end arch armv7ve
 
 begin arch armv7-r
@@ -216,6 +280,14 @@ begin arch armv7-r
  tune flags CO_PROC
  base 7R
  isa ARMv7r
+# ARMv7-r uses VFPv3-d16
+ option fp.sp add VFPv3
+ optalias vfpv3xd fp.sp
+ option fp add VFPv3 FP_DBL
+ optalias vfpv3-d16 fp
+ option idiv add bit_adiv
+ option nofp remove ALL_FP
+ option noidiv remove bit_adiv
 end arch armv7-r
 
 begin arch armv7-m
@@ -223,6 +295,8 @@ begin arch armv7-m
  tune flags CO_PROC
  base 7M
  isa ARMv7m
+# In theory FP is permitted in v7-m, but in practice no implementations exist.
+# leave it out for now.
 end arch armv7-m
 
 begin arch armv7e-m
@@ -230,6 +304,13 @@ begin arch armv7e-m
  tune flags CO_PROC
  base 7EM
  isa ARMv7em
+# fp => VFPv4-sp-d16; fpv5 => FPv5-sp-d16; fp.dp => FPv5-d16
+ option fp add VFPv4
+ optalias vfpv4-sp-d16 fp
+ option fpv5 add FPv5
+ option fp.dp add FPv5 FP_DBL
+ optalias fpv5-d16 fp.dp
+ option nofp remove ALL_FP
 end arch armv7e-m
 
 begin arch armv8-a
@@ -237,20 +318,22 @@ 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 CRYPTO
+ option nocrypto remove ALL_CRYPTO
+ option nofp remove ALL_FP
 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 CRYPTO
+ option nocrypto remove ALL_CRYPTO
+ option nofp remove ALL_FP
 end arch armv8.1-a
 
 begin arch armv8.2-a
@@ -258,15 +341,13 @@ begin arch armv8.2-a
  tune flags CO_PROC
  base 8A
  isa ARMv8_2a
+ option simd add FP_ARMv8 NEON
+ option fp16 add bit_fp16 FP_ARMv8 NEON
+ option crypto add FP_ARMv8 CRYPTO
+ option nocrypto remove ALL_CRYPTO
+ option nofp remove ALL_FP
 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 +359,14 @@ begin arch armv8-m.main
  tune flags CO_PROC
  base 8M_MAIN
  isa ARMv8m_main
+ option dsp add bit_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
 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 +390,8 @@ end arch iwmmxt2
 #   architecture <name>
 #   [fpu <name>]
 #   [isa <additional-isa-flags-list>]
+#   [option <name> add|remove <isa-list>]*
+#   [optalias <name> <optname>]*
 #   [costs <name>]
 # end cpu <name>
 #
@@ -317,7 +399,9 @@ end arch iwmmxt2
 # non-valid punctuation characters to '_'.
 # If specified, tune for specifies a CPU target to use for tuning this core.
 # isa flags are appended to those defined by the architecture.
-
+# Each add option must have a distinct feature set and each remove
+# option must similarly have a distinct feature set.  Option aliases can be
+# added with the optalias statement
 
 # V2/V2A Architecture Processors
 begin cpu arm2
@@ -593,6 +677,7 @@ end cpu ep9312
 
 
 # V5T Architecture Processors
+# These used VFPv1 which isn't supported by GCC
 begin cpu arm10tdmi
  tune flags LDSCHED
  architecture armv5t
@@ -610,6 +695,8 @@ end cpu arm1020t
 begin cpu arm9e
  tune flags LDSCHED
  architecture armv5te
+ fpu vfpv2
+ option nofp remove ALL_FP
  costs 9e
 end cpu arm9e
 
@@ -617,6 +704,8 @@ begin cpu arm946e-s
  cname arm946es
  tune flags LDSCHED
  architecture armv5te
+ fpu vfpv2
+ option nofp remove ALL_FP
  costs 9e
 end cpu arm946e-s
 
@@ -624,6 +713,8 @@ begin cpu arm966e-s
  cname arm966es
  tune flags LDSCHED
  architecture armv5te
+ fpu vfpv2
+ option nofp remove ALL_FP
  costs 9e
 end cpu arm966e-s
 
@@ -631,24 +722,32 @@ begin cpu arm968e-s
  cname arm968es
  tune flags LDSCHED
  architecture armv5te
+ fpu vfpv2
+ option nofp remove ALL_FP
  costs 9e
 end cpu arm968e-s
 
 begin cpu arm10e
  tune flags LDSCHED
  architecture armv5te
+ fpu vfpv2
+ option nofp remove ALL_FP
  costs fastmul
 end cpu arm10e
 
 begin cpu arm1020e
  tune flags LDSCHED
  architecture armv5te
+ fpu vfpv2
+ option nofp remove ALL_FP
  costs fastmul
 end cpu arm1020e
 
 begin cpu arm1022e
  tune flags LDSCHED
  architecture armv5te
+ fpu vfpv2
+ option nofp remove ALL_FP
  costs fastmul
 end cpu arm1022e
 
@@ -701,6 +800,8 @@ begin cpu arm926ej-s
  cname arm926ejs
  tune flags LDSCHED
  architecture armv5tej
+ fpu vfpv2
+ option nofp remove ALL_FP
  costs 9e
 end cpu arm926ej-s
 
@@ -708,6 +809,8 @@ begin cpu arm1026ej-s
  cname arm1026ejs
  tune flags LDSCHED
  architecture armv5tej
+ fpu vfpv2
+ option nofp remove ALL_FP
  costs 9e
 end cpu arm1026ej-s
 
@@ -826,6 +929,20 @@ begin cpu generic-armv7-a
  cname genericv7a
  tune flags LDSCHED
  architecture 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 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-vfpv4 add VFPv4 NEON
+ option nosimd remove ALL_SIMD
+ option nofp remove ALL_FP
  costs cortex
 end cpu generic-armv7-a
 
@@ -833,6 +950,9 @@ begin cpu cortex-a5
  cname cortexa5
  tune flags LDSCHED
  architecture armv7-a
+ fpu neon-fp16
+ option nosimd remove ALL_SIMD
+ option nofp remove ALL_FP
  costs cortex_a5
 end cpu cortex-a5
 
@@ -840,6 +960,9 @@ begin cpu cortex-a7
  cname cortexa7
  tune flags LDSCHED
  architecture armv7ve
+ fpu neon-vfpv4
+ option nosimd remove ALL_SIMD
+ option nofp remove ALL_FP
  costs cortex_a7
 end cpu cortex-a7
 
@@ -847,6 +970,8 @@ begin cpu cortex-a8
  cname cortexa8
  tune flags LDSCHED
  architecture armv7-a
+ fpu neon-vfpv3
+ option nofp remove ALL_FP
  costs cortex_a8
 end cpu cortex-a8
 
@@ -854,6 +979,9 @@ begin cpu cortex-a9
  cname cortexa9
  tune flags LDSCHED
  architecture armv7-a
+ fpu neon-fp16
+ option nosimd remove ALL_SIMD
+ option nofp remove ALL_FP
  costs cortex_a9
 end cpu cortex-a9
 
@@ -862,6 +990,8 @@ begin cpu cortex-a12
  tune for cortex-a17
  tune flags LDSCHED
  architecture armv7ve
+ fpu neon-vfpv4
+ option nofp remove ALL_FP
  costs cortex_a12
 end cpu cortex-a12
 
@@ -869,6 +999,8 @@ begin cpu cortex-a15
  cname cortexa15
  tune flags LDSCHED
  architecture armv7ve
+ fpu neon-vfpv4
+ option nofp remove ALL_FP
  costs cortex_a15
 end cpu cortex-a15
 
@@ -876,6 +1008,8 @@ begin cpu cortex-a17
  cname cortexa17
  tune flags LDSCHED
  architecture armv7ve
+ fpu neon-vfpv4
+ option nofp remove ALL_FP
  costs cortex_a12
 end cpu cortex-a17
 
@@ -890,22 +1024,26 @@ begin cpu cortex-r4f
  cname cortexr4f
  tune flags LDSCHED
  architecture armv7-r
+ fpu vfpv3-d16
  costs cortex
 end cpu cortex-r4f
 
 begin cpu cortex-r5
  cname cortexr5
  tune flags LDSCHED
- architecture armv7-r
- isa bit_adiv
+ architecture armv7-r+idiv
+ fpu vfpv3-d16
+ option nofp.dp remove FP_DBL
+ option nofp remove ALL_FP
  costs cortex
 end cpu cortex-r5
 
 begin cpu cortex-r7
  cname cortexr7
  tune flags LDSCHED
- architecture armv7-r
- isa bit_adiv
+ architecture armv7-r+idiv
+ fpu vfpv3-d16
+ option nofp remove ALL_FP
  costs cortex
 end cpu cortex-r7
 
@@ -913,8 +1051,9 @@ begin cpu cortex-r8
  cname cortexr8
  tune for cortex-r7
  tune flags LDSCHED
- architecture armv7-r
- isa bit_adiv
+ architecture armv7-r+idiv
+ fpu vfpv3-d16
+ option nofp remove ALL_FP
  costs cortex
 end cpu cortex-r8
 
@@ -923,6 +1062,9 @@ begin cpu cortex-m7
  tune flags LDSCHED
  architecture armv7e-m
  isa quirk_no_volatile_ce
+ fpu fpv5-d16
+ option nofp.dp remove FP_DBL
+ option nofp remove ALL_FP
  costs cortex_m7
 end cpu cortex-m7
 
@@ -930,6 +1072,8 @@ begin cpu cortex-m4
  cname cortexm4
  tune flags LDSCHED
  architecture armv7e-m
+ fpu fpv4-sp-d16
+ option nofp remove ALL_FP
  costs v7m
 end cpu cortex-m4
 
@@ -954,6 +1098,8 @@ begin cpu cortex-a15.cortex-a7
  tune for cortex-a7
  tune flags LDSCHED
  architecture armv7ve
+ fpu neon-vfpv4
+ option nofp remove ALL_FP
  costs cortex_a15
 end cpu cortex-a15.cortex-a7
 
@@ -962,6 +1108,8 @@ begin cpu cortex-a17.cortex-a7
  tune for cortex-a7
  tune flags LDSCHED
  architecture armv7ve
+ fpu neon-vfpv4
+ option nofp remove ALL_FP
  costs cortex_a12
 end cpu cortex-a17.cortex-a7
 
@@ -972,6 +1120,9 @@ begin cpu cortex-a32
  tune for cortex-a53
  tune flags LDSCHED
  architecture armv8-a+crc
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
+ option nofp remove ALL_FP
  costs cortex_a35
 end cpu cortex-a32
 
@@ -980,6 +1131,9 @@ begin cpu cortex-a35
  tune for cortex-a53
  tune flags LDSCHED
  architecture armv8-a+crc
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
+ option nofp remove ALL_FP
  costs cortex_a35
 end cpu cortex-a35
 
@@ -987,6 +1141,9 @@ begin cpu cortex-a53
  cname cortexa53
  tune flags LDSCHED
  architecture armv8-a+crc
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
+ option nofp remove ALL_FP
  costs cortex_a53
 end cpu cortex-a53
 
@@ -994,6 +1151,8 @@ begin cpu cortex-a57
  cname cortexa57
  tune flags LDSCHED
  architecture armv8-a+crc
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
  costs cortex_a57
 end cpu cortex-a57
 
@@ -1002,6 +1161,8 @@ begin cpu cortex-a72
  tune for cortex-a57
  tune flags LDSCHED
  architecture armv8-a+crc
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
  costs cortex_a57
 end cpu cortex-a72
 
@@ -1010,6 +1171,8 @@ begin cpu cortex-a73
  tune for cortex-a57
  tune flags LDSCHED
  architecture armv8-a+crc
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
  costs cortex_a73
 end cpu cortex-a73
 
@@ -1017,6 +1180,8 @@ begin cpu exynos-m1
  cname exynosm1
  tune flags LDSCHED
  architecture armv8-a+crc
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
  costs exynosm1
 end cpu exynos-m1
 
@@ -1024,6 +1189,8 @@ begin cpu falkor
  tune for cortex-a57
  tune flags LDSCHED
  architecture armv8-a+crc
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
  costs qdf24xx
 end cpu falkor
 
@@ -1031,12 +1198,16 @@ begin cpu qdf24xx
  tune for cortex-a57
  tune flags LDSCHED
  architecture armv8-a+crc
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
  costs qdf24xx
 end cpu qdf24xx
 
 begin cpu xgene1
  tune flags LDSCHED
  architecture armv8-a
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
  costs xgene1
 end cpu xgene1
 
@@ -1047,6 +1218,8 @@ begin cpu cortex-a57.cortex-a53
  tune for cortex-a53
  tune flags LDSCHED
  architecture armv8-a+crc
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
  costs cortex_a57
 end cpu cortex-a57.cortex-a53
 
@@ -1055,6 +1228,8 @@ begin cpu cortex-a72.cortex-a53
  tune for cortex-a53
  tune flags LDSCHED
  architecture armv8-a+crc
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
  costs cortex_a57
 end cpu cortex-a72.cortex-a53
 
@@ -1063,6 +1238,8 @@ begin cpu cortex-a73.cortex-a35
  tune for cortex-a53
  tune flags LDSCHED
  architecture armv8-a+crc
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
  costs cortex_a73
 end cpu cortex-a73.cortex-a35
 
@@ -1071,6 +1248,8 @@ begin cpu cortex-a73.cortex-a53
  tune for cortex-a53
  tune flags LDSCHED
  architecture armv8-a+crc
+ fpu neon-fp-armv8
+ option crypto add FP_ARMv8 CRYPTO
  costs cortex_a73
 end cpu cortex-a73.cortex-a53
 
@@ -1087,6 +1266,8 @@ begin cpu cortex-m33
  cname cortexm33
  tune flags LDSCHED
  architecture armv8-m.main+dsp
+ fpu fpv5-sp-d16
+ option nofp remove ALL_FP
  costs v7m
 end cpu cortex-m33
 
diff --git a/gcc/config/arm/arm-isa.h b/gcc/config/arm/arm-isa.h
index 7d1e23b..4b5a0f6 100644
--- a/gcc/config/arm/arm-isa.h
+++ b/gcc/config/arm/arm-isa.h
@@ -127,11 +127,25 @@ enum isa_feature
 #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
 
+/* 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	isa_bit_VFPv2, isa_bit_VFPv3, isa_bit_VFPv4, \
-    isa_bit_FPv5, isa_bit_FP_ARMv8, isa_bit_neon, isa_bit_fp16conv, \
-    isa_bit_fp_dbl, isa_bit_fp_d32, isa_bit_crypto
+#define ISA_ALL_FPU_INTERNAL						\
+  isa_bit_VFPv2, isa_bit_VFPv3, isa_bit_VFPv4, isa_bit_FPv5,		\
+  isa_bit_FP_ARMv8, 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
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index cf8b437..25210e2 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -462,8 +462,6 @@ struct arm_build_target
   const char *arch_name;
   /* Preprocessor substring (never NULL).  */
   const char *arch_pp_name;
-  /* CPU identifier for the core we're compiling for (architecturally).  */
-  enum processor_type arch_core;
   /* The base architecture value.  */
   enum base_architecture base_arch;
   /* Bitmap encapsulating the isa_bits for the target environment.  */
@@ -478,5 +476,59 @@ struct arm_build_target
 
 extern struct arm_build_target arm_active_target;
 
+struct cpu_arch_extension
+{
+  /* Feature name.  */
+  const char *const name;
+  /* True if the option is negative (removes extensions).  */
+  bool remove;
+  /* True if the option is an alias for another option with identical effect;
+     the option will be ignored for canonicalization.  */
+  bool alias;
+  /* The modifier bits.  */
+  const enum isa_feature isa_bits[isa_num_bits];
+};
+
+struct cpu_arch_option
+{
+  /* Name for this option.  */
+  const char *name;
+  /* List of feature extensions permitted.  */
+  const struct cpu_arch_extension *extensions;
+  /* Standard feature bits.  */
+  enum isa_feature isa_bits[isa_num_bits];
+};
+
+struct arch_option
+{
+  /* Common option fields.  */
+  cpu_arch_option common;
+  /* Short string for this architecture.  */
+  const char *arch;
+  /* Base architecture, from which this specific architecture is derived.  */
+  enum base_architecture base_arch;
+  /* Default tune target (in the absence of any more specific data).  */
+  enum processor_type tune_id;
+};
+
+struct cpu_option
+{
+  /* Common option fields.  */
+  cpu_arch_option common;
+  /* Architecture upon which this CPU is based.  */
+  enum arch_type arch;
+};
+
+extern const arch_option all_architectures[];
+extern const cpu_option all_cores[];
+
+const cpu_option *arm_parse_cpu_option_name (const cpu_option *, const char *,
+					     const char *);
+const arch_option *arm_parse_arch_option_name (const arch_option *,
+					       const char *, const char *);
+void arm_parse_option_features (sbitmap, const cpu_arch_option *,
+				const char *);
+
+void arm_initialize_isa (sbitmap, const enum isa_feature *);
 
 #endif /* ! GCC_ARM_PROTOS_H */
diff --git a/gcc/config/arm/arm-tables.opt b/gcc/config/arm/arm-tables.opt
index cbcd85d..f7b4339 100644
--- a/gcc/config/arm/arm-tables.opt
+++ b/gcc/config/arm/arm-tables.opt
@@ -440,31 +440,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)
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 42b0e86..7f6c5a7 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -65,6 +65,7 @@
 #include "optabs-libfuncs.h"
 #include "gimplify.h"
 #include "gimple.h"
+#include "selftest.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -233,6 +234,7 @@ static tree arm_build_builtin_va_list (void);
 static void arm_expand_builtin_va_start (tree, rtx);
 static tree arm_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
 static void arm_option_override (void);
+static void arm_option_save (struct cl_target_option *, struct gcc_options *);
 static void arm_option_restore (struct gcc_options *,
 				struct cl_target_option *);
 static void arm_override_options_after_change (void);
@@ -413,6 +415,9 @@ static const struct attribute_spec arm_attribute_table[] =
 #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
 #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE arm_override_options_after_change
 
+#undef TARGET_OPTION_SAVE
+#define TARGET_OPTION_SAVE arm_option_save
+
 #undef TARGET_OPTION_RESTORE
 #define TARGET_OPTION_RESTORE arm_option_restore
 
@@ -770,7 +775,6 @@ static const struct attribute_spec arm_attribute_table[] =
 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 2
 
-struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Obstack for minipool constant handling.  */
 static struct obstack minipool_obstack;
@@ -971,18 +975,13 @@ int arm_regs_in_sequence[] =
 
 /* Initialization code.  */
 
-struct processors
+struct cpu_tune
 {
-  const char *const name;
-  enum processor_type core;
+  enum processor_type scheduler;
   unsigned int tune_flags;
-  const char *arch;
-  enum base_architecture base_arch;
-  enum isa_feature isa_bits[isa_num_bits];
-  const struct tune_params *const tune;
+  const struct tune_params *tune;
 };
 
-
 #define ARM_PREFETCH_NOT_BENEFICIAL { 0, -1, -1 }
 #define ARM_PREFETCH_BENEFICIAL(num_slots,l1_size,l1_line_size) \
   {								\
@@ -2924,9 +2923,22 @@ arm_override_options_after_change (void)
   arm_override_options_after_change_1 (&global_options);
 }
 
+/* Implement TARGET_OPTION_SAVE.  */
 static void
-arm_option_restore (struct gcc_options *, struct cl_target_option *ptr)
+arm_option_save (struct cl_target_option *ptr, struct gcc_options *opts)
 {
+  ptr->x_arm_arch_string = opts->x_arm_arch_string;
+  ptr->x_arm_cpu_string = opts->x_arm_cpu_string;
+  ptr->x_arm_tune_string = opts->x_arm_tune_string;
+}
+
+/* Implement TARGET_OPTION_RESTORE.  */
+static void
+arm_option_restore (struct gcc_options *opts, struct cl_target_option *ptr)
+{
+  opts->x_arm_arch_string = ptr->x_arm_arch_string;
+  opts->x_arm_cpu_string = ptr->x_arm_cpu_string;
+  opts->x_arm_tune_string = ptr->x_arm_tune_string;
   arm_configure_build_target (&arm_active_target, ptr, &global_options_set,
 			      false);
 }
@@ -3034,16 +3046,6 @@ arm_option_override_internal (struct gcc_options *opts,
 #endif
 }
 
-/* Convert a static initializer array of feature bits to sbitmap
-   representation.  */
-static void
-arm_initialize_isa (sbitmap isa, const enum isa_feature *isa_bits)
-{
-  bitmap_clear (isa);
-  while (*isa_bits != isa_nobit)
-    bitmap_set_bit (isa, *(isa_bits++));
-}
-
 static sbitmap isa_all_fpubits;
 static sbitmap isa_quirkbits;
 
@@ -3056,86 +3058,117 @@ arm_configure_build_target (struct arm_build_target *target,
 			    struct gcc_options *opts_set,
 			    bool warn_compatible)
 {
-  const struct processors *arm_selected_tune = NULL;
-  const struct processors *arm_selected_arch = NULL;
-  const struct processors *arm_selected_cpu = NULL;
-  const struct arm_fpu_desc *arm_selected_fpu = NULL;
+  const cpu_option *arm_selected_tune = NULL;
+  const arch_option *arm_selected_arch = NULL;
+  const cpu_option *arm_selected_cpu = NULL;
+  const 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_option)
-    arm_selected_arch = &all_architectures[opts->x_arm_arch_option];
+  if (opts_set->x_arm_arch_string)
+    {
+      arm_selected_arch = arm_parse_arch_option_name (all_architectures,
+						      "-march",
+						      opts->x_arm_arch_string);
+      arch_opts = strchr (opts->x_arm_arch_string, '+');
+    }
 
-  if (opts_set->x_arm_cpu_option)
+  if (opts_set->x_arm_cpu_string)
     {
-      arm_selected_cpu = &all_cores[(int) opts->x_arm_cpu_option];
-      arm_selected_tune = &all_cores[(int) opts->x_arm_cpu_option];
+      arm_selected_cpu = arm_parse_cpu_option_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_option)
-    arm_selected_tune = &all_cores[(int) opts->x_arm_tune_option];
+  if (opts_set->x_arm_tune_string)
+    {
+      arm_selected_tune = arm_parse_cpu_option_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_initialize_isa (target->isa, arm_selected_arch->common.isa_bits);
+      arm_parse_option_features (target->isa, &arm_selected_arch->common,
+				 arch_opts);
 
       if (arm_selected_cpu)
 	{
 	  auto_sbitmap cpu_isa (isa_num_bits);
+	  auto_sbitmap isa_delta (isa_num_bits);
 
-	  arm_initialize_isa (cpu_isa, arm_selected_cpu->isa_bits);
-	  bitmap_xor (cpu_isa, cpu_isa, target->isa);
+	  arm_initialize_isa (cpu_isa, arm_selected_cpu->common.isa_bits);
+	  arm_parse_option_features (cpu_isa, &arm_selected_cpu->common,
+				     cpu_opts);
+	  bitmap_xor (isa_delta, cpu_isa, target->isa);
 	  /* Ignore any bits that are quirk bits.  */
-	  bitmap_and_compl (cpu_isa, cpu_isa, isa_quirkbits);
+	  bitmap_and_compl (isa_delta, isa_delta, isa_quirkbits);
 	  /* Ignore (for now) any bits that might be set by -mfpu.  */
-	  bitmap_and_compl (cpu_isa, cpu_isa, isa_all_fpubits);
+	  bitmap_and_compl (isa_delta, isa_delta, isa_all_fpubits);
 
-	  if (!bitmap_empty_p (cpu_isa))
+	  if (!bitmap_empty_p (isa_delta))
 	    {
 	      if (warn_compatible)
 		warning (0, "switch -mcpu=%s conflicts with -march=%s switch",
-			 arm_selected_cpu->name, arm_selected_arch->name);
+			 arm_selected_cpu->common.name,
+			 arm_selected_arch->common.name);
 	      /* -march wins for code generation.
 		 -mcpu wins for default tuning.  */
 	      if (!arm_selected_tune)
 		arm_selected_tune = arm_selected_cpu;
 
-	      arm_selected_cpu = arm_selected_arch;
-	      target->arch_name = arm_selected_arch->name;
+	      arm_selected_cpu = all_cores + arm_selected_arch->tune_id;
+	      target->arch_name = arm_selected_arch->common.name;
 	    }
 	  else
 	    {
 	      /* Architecture and CPU are essentially the same.
 		 Prefer the CPU setting.  */
-	      arm_selected_arch = NULL;
-	      target->core_name = arm_selected_cpu->name;
+	      arm_selected_arch = all_architectures + arm_selected_cpu->arch;
+	      target->core_name = arm_selected_cpu->common.name;
+	      /* Copy the CPU's capabilities, so that we inherit the
+		 appropriate extensions and quirks.  */
+	      bitmap_copy (target->isa, cpu_isa);
 	    }
 	}
       else
 	{
 	  /* Pick a CPU based on the architecture.  */
-	  arm_selected_cpu = arm_selected_arch;
-	  target->arch_name = arm_selected_arch->name;
+	  arm_selected_cpu = all_cores + arm_selected_arch->tune_id;
+	  target->arch_name = arm_selected_arch->common.name;
 	  /* Note: target->core_name is left unset in this path.  */
 	}
     }
   else if (arm_selected_cpu)
     {
-      target->core_name = arm_selected_cpu->name;
-      arm_initialize_isa (target->isa, arm_selected_cpu->isa_bits);
+      target->core_name = arm_selected_cpu->common.name;
+      arm_initialize_isa (target->isa, arm_selected_cpu->common.isa_bits);
+      arm_parse_option_features (target->isa, &arm_selected_cpu->common,
+				 cpu_opts);
+      arm_selected_arch = all_architectures + arm_selected_cpu->arch;
     }
-  /* If the user did not specify a processor, choose one for them.  */
+  /* If the user did not specify a processor or architecture, choose
+     one for them.  */
   else
     {
-      const struct processors * sel;
+      const cpu_option *sel;
       auto_sbitmap sought_isa (isa_num_bits);
       bitmap_clear (sought_isa);
       auto_sbitmap default_isa (isa_num_bits);
 
-      arm_selected_cpu = &all_cores[TARGET_CPU_DEFAULT];
-      gcc_assert (arm_selected_cpu->name);
+      arm_selected_cpu = arm_parse_cpu_option_name (all_cores, "default CPU",
+						    TARGET_CPU_DEFAULT);
+      cpu_opts = strchr (TARGET_CPU_DEFAULT, '+');
+      gcc_assert (arm_selected_cpu->common.name);
 
       /* RWE: All of the selection logic below (to the end of this
 	 'if' clause) looks somewhat suspect.  It appears to be mostly
@@ -3144,7 +3177,9 @@ arm_configure_build_target (struct arm_build_target *target,
 	 user might be expecting).  I think it should be removed once
 	 support for the pre-thumb era cores is removed.  */
       sel = arm_selected_cpu;
-      arm_initialize_isa (default_isa, sel->isa_bits);
+      arm_initialize_isa (default_isa, sel->common.isa_bits);
+      arm_parse_option_features (default_isa, &arm_selected_cpu->common,
+				 cpu_opts);
 
       /* Now check to see if the user has specified any command line
 	 switches that require certain abilities from the cpu.  */
@@ -3177,18 +3212,18 @@ arm_configure_build_target (struct arm_build_target *target,
 	  /* Try to locate a CPU type that supports all of the abilities
 	     of the default CPU, plus the extra abilities requested by
 	     the user.  */
-	  for (sel = all_cores; sel->name != NULL; sel++)
+	  for (sel = all_cores; sel->common.name != NULL; sel++)
 	    {
-	      arm_initialize_isa (candidate_isa, sel->isa_bits);
+	      arm_initialize_isa (candidate_isa, sel->common.isa_bits);
 	      /* An exact match?  */
 	      if (bitmap_equal_p (default_isa, candidate_isa))
 		break;
 	    }
 
-	  if (sel->name == NULL)
+	  if (sel->common.name == NULL)
 	    {
 	      unsigned current_bit_count = isa_num_bits;
-	      const struct processors * best_fit = NULL;
+	      const cpu_option *best_fit = NULL;
 
 	      /* Ideally we would like to issue an error message here
 		 saying that it was not possible to find a CPU compatible
@@ -3202,9 +3237,9 @@ arm_configure_build_target (struct arm_build_target *target,
 		 command line options we scan the array again looking
 		 for a best match.  The best match must have at least
 		 the capabilities of the perfect match.  */
-	      for (sel = all_cores; sel->name != NULL; sel++)
+	      for (sel = all_cores; sel->common.name != NULL; sel++)
 		{
-		  arm_initialize_isa (candidate_isa, sel->isa_bits);
+		  arm_initialize_isa (candidate_isa, sel->common.isa_bits);
 
 		  if (bitmap_subset_p (default_isa, candidate_isa))
 		    {
@@ -3230,11 +3265,15 @@ arm_configure_build_target (struct arm_build_target *target,
 
       /* Now we know the CPU, we can finally initialize the target
 	 structure.  */
-      target->core_name = arm_selected_cpu->name;
-      arm_initialize_isa (target->isa, arm_selected_cpu->isa_bits);
+      target->core_name = arm_selected_cpu->common.name;
+      arm_initialize_isa (target->isa, arm_selected_cpu->common.isa_bits);
+      arm_parse_option_features (target->isa, &arm_selected_cpu->common,
+				 cpu_opts);
+      arm_selected_arch = all_architectures + arm_selected_cpu->arch;
     }
 
   gcc_assert (arm_selected_cpu);
+  gcc_assert (arm_selected_arch);
 
   if (opts->x_arm_fpu_index != TARGET_FPU_auto)
     {
@@ -3245,30 +3284,29 @@ 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];
+    arm_selected_tune = arm_selected_cpu;
+  else /* Validate the features passed to -mtune.  */
+    arm_parse_option_features (NULL, &arm_selected_tune->common, tune_opts);
+
+  const cpu_tune *tune_data = &all_tunes[arm_selected_tune - all_cores];
 
   /* Finish initializing the target structure.  */
-  target->arch_pp_name = arm_selected_cpu->arch;
-  target->base_arch = arm_selected_cpu->base_arch;
-  target->arch_core = arm_selected_cpu->core;
+  target->arch_pp_name = arm_selected_arch->arch;
+  target->base_arch = arm_selected_arch->base_arch;
 
-  target->tune_flags = arm_selected_tune->tune_flags;
-  target->tune = arm_selected_tune->tune;
-  target->tune_core = arm_selected_tune->core;
+  target->tune_flags = tune_data->tune_flags;
+  target->tune = tune_data->tune;
+  target->tune_core = tune_data->scheduler;
 }
 
 /* Fix up any incompatible options that the user has specified.  */
 static void
 arm_option_override (void)
 {
-  static const enum isa_feature fpu_bitlist[] = { ISA_ALL_FPU, isa_nobit };
+  static const enum isa_feature fpu_bitlist[]
+    = { ISA_ALL_FPU_INTERNAL, isa_nobit };
   static const enum isa_feature quirk_bitlist[] = { ISA_ALL_QUIRKS, isa_nobit};
   cl_target_option opts;
 
@@ -3282,17 +3320,10 @@ arm_option_override (void)
 
   if (!global_options_set.x_arm_fpu_index)
     {
-      const char *target_fpu_name;
       bool ok;
       int fpu_index;
 
-#ifdef FPUTYPE_DEFAULT
-      target_fpu_name = FPUTYPE_DEFAULT;
-#else
-      target_fpu_name = "vfp";
-#endif
-
-      ok = opt_enum_arg_to_value (OPT_mfpu_, target_fpu_name, &fpu_index,
+      ok = opt_enum_arg_to_value (OPT_mfpu_, FPUTYPE_AUTO, &fpu_index,
 				  CL_TARGET);
       gcc_assert (ok);
       arm_fpu_index = (enum fpu_type) fpu_index;
@@ -3433,8 +3464,7 @@ arm_option_override (void)
     {
       if (arm_abi == ARM_ABI_IWMMXT)
 	arm_pcs_default = ARM_PCS_AAPCS_IWMMXT;
-      else if (arm_float_abi == ARM_FLOAT_ABI_HARD
-	       && TARGET_HARD_FLOAT)
+      else if (TARGET_HARD_FLOAT_ABI)
 	{
 	  arm_pcs_default = ARM_PCS_AAPCS_VFP;
 	  if (!bitmap_bit_p (arm_active_target.isa, isa_bit_VFPv2))
@@ -26121,6 +26151,41 @@ 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 arch_option *arch
+    = arm_parse_arch_option_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->common.extensions)
+    return;
+
+  for (const struct cpu_arch_extension *opt = arch->common.extensions;
+       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)
 {
@@ -26135,7 +26200,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)
 	    {
@@ -26148,24 +26213,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);
@@ -26189,7 +26238,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)
@@ -30384,11 +30433,23 @@ arm_option_print (FILE *file, int indent, struct cl_target_option *ptr)
   fpu_name = (ptr->x_arm_fpu_index == TARGET_FPU_auto
 	      ? "auto" : all_fpus[ptr->x_arm_fpu_index].name);
 
-  fprintf (file, "%*sselected arch %s\n", indent, "",
+  fprintf (file, "%*sselected isa %s\n", indent, "",
 	   TARGET_THUMB2_P (flags) ? "thumb2" :
 	   TARGET_THUMB_P (flags) ? "thumb1" :
 	   "arm");
 
+  if (ptr->x_arm_arch_string)
+    fprintf (file, "%*sselected architecture %s\n", indent, "",
+	     ptr->x_arm_arch_string);
+
+  if (ptr->x_arm_cpu_string)
+    fprintf (file, "%*sselected CPU %s\n", indent, "",
+	     ptr->x_arm_cpu_string);
+
+  if (ptr->x_arm_tune_string)
+    fprintf (file, "%*sselected tune %s\n", indent, "",
+	     ptr->x_arm_tune_string);
+
   fprintf (file, "%*sselected fpu %s\n", indent, "", fpu_name);
 }
 
@@ -30651,7 +30712,7 @@ arm_identify_fpu_from_isa (sbitmap isa)
   if (bitmap_empty_p (fpubits))
     return "softvfp";
 
-  for (unsigned int i = 0; i < ARRAY_SIZE (all_fpus); i++)
+  for (unsigned int i = 0; i < TARGET_FPU_auto; i++)
     {
       arm_initialize_isa (cand_fpubits, all_fpus[i].isa_bits);
       if (bitmap_equal_p (fpubits, cand_fpubits))
@@ -31161,4 +31222,84 @@ arm_coproc_ldc_stc_legitimate_address (rtx op)
     }
   return false;
 }
+
+#if CHECKING_P
+namespace selftest {
+
+/* Scan the static data tables generated by parsecpu.awk looking for
+   potential issues with the data.  We primarily check for
+   inconsistencies in the option extensions at present (extensions
+   that duplicate others but aren't marked as aliases).  Furthermore,
+   for correct canonicalization later options must never be a subset
+   of an earlier option.  */
+static void
+arm_test_cpu_arch_data (void)
+{
+  const arch_option *arch;
+  const cpu_option *cpu;
+  auto_sbitmap isa1 (isa_num_bits);
+  auto_sbitmap isa2 (isa_num_bits);
+
+  for (arch = all_architectures; arch->common.name != NULL; ++arch)
+    {
+      const cpu_arch_extension *ext1, *ext2;
+
+      if (arch->common.extensions == NULL)
+	continue;
+
+      for (ext1 = arch->common.extensions; ext1->name != NULL; ++ext1)
+	{
+	  if (ext1->alias)
+	    continue;
+
+	  arm_initialize_isa (isa1, ext1->isa_bits);
+	  for (ext2 = ext1 + 1; ext2->name != NULL; ++ext2)
+	    {
+	      if (ext2->alias || ext1->remove != ext2->remove)
+		continue;
+
+	      arm_initialize_isa (isa2, ext2->isa_bits);
+	      ASSERT_TRUE (!bitmap_subset_p (isa2, isa1));
+	    }
+	}
+    }
+
+  for (cpu = all_cores; cpu->common.name != NULL; ++cpu)
+    {
+      const cpu_arch_extension *ext1, *ext2;
+
+      if (cpu->common.extensions == NULL)
+	continue;
+
+      for (ext1 = cpu->common.extensions; ext1->name != NULL; ++ext1)
+	{
+	  if (ext1->alias)
+	    continue;
+
+	  arm_initialize_isa (isa1, ext1->isa_bits);
+	  for (ext2 = ext1 + 1; ext2->name != NULL; ++ext2)
+	    {
+	      if (ext2->alias || ext1->remove != ext2->remove)
+		continue;
+
+	      arm_initialize_isa (isa2, ext2->isa_bits);
+	      ASSERT_TRUE (!bitmap_subset_p (isa2, isa1));
+	    }
+	}
+    }
+}
+
+static void
+arm_run_selftests (void)
+{
+  arm_test_cpu_arch_data ();
+}
+} /* Namespace selftest.  */
+
+#undef TARGET_RUN_TARGET_SELFTESTS
+#define TARGET_RUN_TARGET_SELFTESTS selftest::arm_run_selftests
+#endif /* CHECKING_P */
+
+struct gcc_target targetm = TARGET_INITIALIZER;
+
 #include "gt-arm.h"
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index f9e4356..43d4477 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -119,9 +119,14 @@ extern tree arm_fp16_type_node;
 #define TARGET_32BIT_P(flags)  (TARGET_ARM_P (flags) || TARGET_THUMB2_P (flags))
 
 /* Run-time Target Specification.  */
-#define TARGET_SOFT_FLOAT		(arm_float_abi == ARM_FLOAT_ABI_SOFT)
 /* Use hardware floating point instructions. */
-#define TARGET_HARD_FLOAT		(arm_float_abi != ARM_FLOAT_ABI_SOFT)
+#define TARGET_HARD_FLOAT	(arm_float_abi != ARM_FLOAT_ABI_SOFT	\
+				 && bitmap_bit_p (arm_active_target.isa, \
+						  isa_bit_VFPv2))
+#define TARGET_SOFT_FLOAT	(!TARGET_HARD_FLOAT)
+/* User has permitted use of FP instructions, if they exist for this
+   target.  */
+#define TARGET_MAYBE_HARD_FLOAT (arm_float_abi != ARM_FLOAT_ABI_SOFT)
 /* Use hardware floating point calling convention.  */
 #define TARGET_HARD_FLOAT_ABI		(arm_float_abi == ARM_FLOAT_ABI_HARD)
 #define TARGET_IWMMXT			(arm_arch_iwmmxt)
@@ -2215,46 +2220,55 @@ extern int making_const_table;
   (TARGET_NEON ? (TARGET_ARM_FP & (0xff ^ 0x08)) \
 	       : 0)
 
+/* Name of the automatic fpu-selection option.  */
+#define FPUTYPE_AUTO "auto"
+
 /* The maximum number of parallel loads or stores we support in an ldm/stm
    instruction.  */
 #define MAX_LDM_STM_OPS 4
 
-#define BIG_LITTLE_SPEC \
-   " %{mcpu=*:-mcpu=%:rewrite_mcpu(%{mcpu=*:%*})}"
-
 extern const char *arm_rewrite_mcpu (int argc, const char **argv);
-#define BIG_LITTLE_CPU_SPEC_FUNCTIONS \
-  { "rewrite_mcpu", arm_rewrite_mcpu },
+extern const char *arm_rewrite_march (int argc, const char **argv);
+#define ASM_CPU_SPEC_FUNCTIONS			\
+  { "rewrite_mcpu", arm_rewrite_mcpu },	\
+  { "rewrite_march", arm_rewrite_march },
 
-#define ASM_CPU_SPEC \
-   " %{mcpu=generic-*:-march=%*;"				\
-   "   :%{march=*:-march=%*}}"					\
-   BIG_LITTLE_SPEC
+#define ASM_CPU_SPEC							\
+  " %{mcpu=generic-*:-march=%:rewrite_march(%{mcpu=generic-*:%*});"	\
+  "   march=*:-march=%:rewrite_march(%{march=*:%*});"		\
+  "   mcpu=*:-mcpu=%:rewrite_mcpu(%{mcpu=*:%*})"			\
+  " }"
 
 extern const char *arm_target_thumb_only (int argc, const char **argv);
-#define TARGET_MODE_SPEC_FUNCTIONS					\
+#define TARGET_MODE_SPEC_FUNCTIONS			\
   { "target_mode_check", arm_target_thumb_only },
 
 /* -mcpu=native handling only makes sense with compiler running on
    an ARM chip.  */
 #if defined(__arm__)
 extern const char *host_detect_local_cpu (int argc, const char **argv);
-# define EXTRA_SPEC_FUNCTIONS						\
-  { "local_cpu_detect", host_detect_local_cpu },			\
-  BIG_LITTLE_CPU_SPEC_FUNCTIONS						\
-  TARGET_MODE_SPEC_FUNCTIONS
-
-# define MCPU_MTUNE_NATIVE_SPECS					\
-   " %{march=native:%<march=native %:local_cpu_detect(arch)}"		\
-   " %{mcpu=native:%<mcpu=native %:local_cpu_detect(cpu)}"		\
+# define MCPU_MTUNE_NATIVE_FUNCTIONS			\
+  { "local_cpu_detect", host_detect_local_cpu },
+# define MCPU_MTUNE_NATIVE_SPECS				\
+   " %{march=native:%<march=native %:local_cpu_detect(arch)}"	\
+   " %{mcpu=native:%<mcpu=native %:local_cpu_detect(cpu)}"	\
    " %{mtune=native:%<mtune=native %:local_cpu_detect(tune)}"
 #else
+# define MCPU_MTUNE_NATIVE_FUNCTIONS
 # define MCPU_MTUNE_NATIVE_SPECS ""
-# define EXTRA_SPEC_FUNCTIONS						\
-	BIG_LITTLE_CPU_SPEC_FUNCTIONS					\
-	TARGET_MODE_SPEC_FUNCTIONS
 #endif
 
+const char *arm_canon_arch_option (int argc, const char **argv);
+
+#define CANON_ARCH_SPEC_FUNCTION		\
+  { "canon_arch", arm_canon_arch_option },
+
+# define EXTRA_SPEC_FUNCTIONS			\
+  MCPU_MTUNE_NATIVE_FUNCTIONS			\
+  ASM_CPU_SPEC_FUNCTIONS			\
+  CANON_ARCH_SPEC_FUNCTION			\
+  TARGET_MODE_SPEC_FUNCTIONS
+
 /* Automatically add -mthumb for Thumb-only targets if mode isn't specified
    via the configuration option --with-mode or via the command line. The
    function target_mode_check is called to do the check with either:
@@ -2262,9 +2276,21 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
    - an array of -mcpu values if any is given;
    - an empty array.  */
 #define TARGET_MODE_SPECS						\
-  " %{!marm:%{!mthumb:%:target_mode_check(%{march=*:%*;mcpu=*:%*;:})}}"
+  " %{!marm:%{!mthumb:%:target_mode_check(%{march=*:arch %*;mcpu=*:cpu %*;:})}}"
+
+/* Generate a canonical string to represent the architecture selected.  */
+#define ARCH_CANONICAL_SPECS				\
+  " -march=%:canon_arch(%{mcpu=*: cpu %*} "		\
+  "                     %{march=*: arch %*} "		\
+  "                     %{mfpu=*: fpu %*} "		\
+  "                     %{mfloat-abi=*: abi %*}"	\
+  "                     %<march=*) "
+
+#define DRIVER_SELF_SPECS			\
+  MCPU_MTUNE_NATIVE_SPECS			\
+  TARGET_MODE_SPECS				\
+  ARCH_CANONICAL_SPECS
 
-#define DRIVER_SELF_SPECS MCPU_MTUNE_NATIVE_SPECS TARGET_MODE_SPECS
 #define TARGET_SUPPORTS_WIDE_INT 1
 
 /* For switching between functions with different target attributes.  */
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index 9f8116d..dad5257 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -21,6 +21,15 @@
 HeaderInclude
 config/arm/arm-opts.h
 
+TargetSave
+const char *x_arm_arch_string
+
+TargetSave
+const char *x_arm_cpu_string
+
+TargetSave
+const char *x_arm_tune_string
+
 Enum
 Name(tls_type) Type(enum arm_tls_type)
 TLS dialect to use:
@@ -73,7 +82,7 @@ mapcs-stack-check
 Target Report Mask(APCS_STACK) Undocumented
 
 march=
-Target RejectNegative ToLower Joined Enum(arm_arch) Var(arm_arch_option) Save
+Target RejectNegative ToLower Joined Var(arm_arch_string)
 Specify the name of the target architecture.
 
 ; Other arm_arch values are loaded from arm-tables.opt
@@ -82,7 +91,7 @@ EnumValue
 Enum(arm_arch) String(native) Value(-1) DriverOnly
 
 marm
-Target Report RejectNegative InverseMask(THUMB)
+Target Report RejectNegative Negative(mthumb) InverseMask(THUMB)
 Generate code in 32 bit ARM state.
 
 mbig-endian
@@ -98,7 +107,7 @@ Target Report Mask(CALLER_INTERWORKING)
 Thumb: Assume function pointers may go to non-Thumb aware code.
 
 mcpu=
-Target RejectNegative ToLower Joined Enum(processor_type) Var(arm_cpu_option) Init(TARGET_CPU_arm_none) Save
+Target RejectNegative ToLower Joined Var(arm_cpu_string)
 Specify the name of the target CPU.
 
 mfloat-abi=
@@ -186,7 +195,7 @@ Target RejectNegative Joined UInteger Var(arm_structure_size_boundary) Init(DEFA
 Specify the minimum bit alignment of structures.
 
 mthumb
-Target Report RejectNegative Mask(THUMB) Save
+Target Report RejectNegative Negative(marm) Mask(THUMB) Save
 Generate code for Thumb state.
 
 mthumb-interwork
@@ -223,7 +232,7 @@ Target Report Mask(TPCS_LEAF_FRAME)
 Thumb: Generate (leaf) stack frames even if not needed.
 
 mtune=
-Target RejectNegative ToLower Joined Enum(processor_type) Var(arm_tune_option) Init(TARGET_CPU_arm_none) Save
+Target RejectNegative ToLower Joined Var(arm_tune_string)
 Tune code for the given processor.
 
 mprint-tune-info
diff --git a/gcc/config/arm/bpabi.h b/gcc/config/arm/bpabi.h
index 56a4a47..64db83c 100644
--- a/gcc/config/arm/bpabi.h
+++ b/gcc/config/arm/bpabi.h
@@ -33,10 +33,6 @@
 #undef ARM_UNWIND_INFO
 #define ARM_UNWIND_INFO 1
 
-/* Section 4.1 of the AAPCS requires the use of VFP format.  */
-#undef  FPUTYPE_DEFAULT
-#define FPUTYPE_DEFAULT "vfp"
-
 /* TARGET_BIG_ENDIAN_DEFAULT is set in
    config.gcc for big endian configurations.  */
 #if TARGET_BIG_ENDIAN_DEFAULT
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index f119b87..85fdee6 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -64,7 +64,7 @@
 %{mapcs-*:-mapcs-%*} \
 %(subtarget_asm_float_spec) \
 %{mthumb-interwork:-mthumb-interwork} \
-%{mfloat-abi=*} %{mfpu=*} \
+%{mfloat-abi=*} %{!mfpu=auto: %{mfpu=*}} \
 %(subtarget_extra_asm_spec)"
 #endif
 
@@ -107,10 +107,6 @@
 #define TARGET_DEFAULT (MASK_APCS_FRAME)
 #endif
 
-#ifndef MULTILIB_DEFAULTS
-#define MULTILIB_DEFAULTS \
-  { "marm", "mlittle-endian", "mfloat-abi=soft", "mno-thumb-interwork", "fno-leading-underscore" }
-#endif
 
 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
 
diff --git a/gcc/config/arm/linux-elf.h b/gcc/config/arm/linux-elf.h
index 3d62367..cd4fc3b 100644
--- a/gcc/config/arm/linux-elf.h
+++ b/gcc/config/arm/linux-elf.h
@@ -83,9 +83,6 @@
     }						\
   while (0)
 
-#undef  FPUTYPE_DEFAULT
-#define FPUTYPE_DEFAULT "vfp"
-
 /* Call the function profiler with a given profile label.  */
 #undef  ARM_FUNCTION_PROFILER
 #define ARM_FUNCTION_PROFILER(STREAM, LABELNO)  			\
diff --git a/gcc/config/arm/netbsd-elf.h b/gcc/config/arm/netbsd-elf.h
index 8811af7..02ff316 100644
--- a/gcc/config/arm/netbsd-elf.h
+++ b/gcc/config/arm/netbsd-elf.h
@@ -153,7 +153,3 @@ do									\
     (void) sysarch (0, &s);						\
   }									\
 while (0)
-
-#undef FPUTYPE_DEFAULT
-#define FPUTYPE_DEFAULT "vfp"
-
diff --git a/gcc/config/arm/parsecpu.awk b/gcc/config/arm/parsecpu.awk
index dac11a0..b6e5093 100644
--- a/gcc/config/arm/parsecpu.awk
+++ b/gcc/config/arm/parsecpu.awk
@@ -102,6 +102,17 @@ function gen_headers () {
     print "  TARGET_CPU_arm_none"
     print "};\n"
 
+    print "enum arch_type"
+    print "{"
+
+    narchs = split (arch_list, archs)
+
+    for (n = 1; n <= narchs; n++) {
+	print "  TARGET_ARCH_"arch_cnames[archs[n]]","
+    }
+    print "  TARGET_ARCH_arm_none"
+    print "};\n"
+
     print "enum fpu_type"
     print "{"
 
@@ -117,14 +128,14 @@ function gen_headers () {
 function gen_data () {
     boilerplate("C")
 
-    print "static const struct processors all_cores[] ="
+    print "static const cpu_tune all_tunes[] ="
     print "{"
 
     ncpus = split (cpu_list, cpus)
 
     for (n = 1; n <= ncpus; n++) {
-	print "  {"
-	print "    \"" cpus[n] "\","
+	print "  { /* " cpus[n] ".  */"
+	# scheduler
 	if (cpus[n] in cpu_tune_for) {
 	    if (! (cpu_tune_for[cpus[n]] in cpu_cnames)) {
 		fatal("unknown \"tune for\" target " cpu_tune_for[cpus[n]] \
@@ -134,59 +145,170 @@ function gen_data () {
 	} else {
 	    print "    TARGET_CPU_" cpu_cnames[cpus[n]] ","
 	}
+	# tune_flags
 	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])
-	}
-	print "    \"" arch_base[cpu_arch[cpus[n]]] "\", BASE_ARCH_" \
-	    arch_base[cpu_arch[cpus[n]]] ","
-	print "    {"
-	print "      " arch_isa[cpu_arch[cpus[n]]] ","
-	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 "    },"
+	# tune
 	print "    &arm_" cpu_cost[cpus[n]] "_tune"
 	print "  },"
     }
+    print "  {TARGET_CPU_arm_none, 0, NULL}"
+    print "};"
+    
+}
 
-    print "  {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0," \
-	" {isa_nobit}, NULL}"
-    print "};\n"
+function gen_comm_data () {
+    boilerplate("C")
+
+    ncpus = split (cpu_list, cpus)
+
+    for (n = 1; n <= ncpus; n++) {
+	if (cpus[n] in cpu_opts) {
+	    print "static const cpu_arch_extension 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]] ", false,"
+		print "    { " cpu_opt_isa[cpus[n],opts[opt]] ", isa_nobit }"
+		print "  },"
+	    }
+	    if (cpus[n] in cpu_optaliases) {
+		naliases = split (cpu_optaliases[cpus[n]], aliases)
+		for (alias = 1; alias <= naliases; alias++) {
+		    if (! ((cpus[n], \
+			    cpu_opt_alias[cpus[n],aliases[alias]]) in \
+			   cpu_opt_isa)) {
+			fatal("Alias " aliases[alias] " target not defined " \
+			      "for CPU " cpus[n])
+		    }
+		    equiv=cpu_opt_alias[cpus[n],aliases[alias]]
+		    print "  {"
+		    print "    \"" aliases[alias] "\", " \
+			cpu_opt_remove[cpus[n],equiv] ", true, "
+		    print "    { " cpu_opt_isa[cpus[n],equiv] ", isa_nobit }"
+		    print "  },"
+		}
+	    }
+	    print "  { NULL, false, false, {isa_nobit}}"
+	    print "};\n"
+	}
+    }
 
-    print "static const struct processors all_architectures[] ="
+    print "const cpu_option all_cores[] ="
     print "{"
 
+    for (n = 1; n <= ncpus; n++) {
+	print "  {"
+	print "    {"
+	# common.name
+	print "      \"" cpus[n] "\","
+	# common.extensions
+	if (cpus[n] in cpu_opts) {
+	    print "      cpu_opttab_" cpu_cnames[cpus[n]] ","
+	} else print "      NULL,"
+	# common.isa_bits
+	nfeats = split (cpu_arch[cpus[n]], feats, "+")
+	if (! (feats[1] in arch_isa)) {
+	    fatal("unknown arch " feats[1] " for cpu " cpus[n])
+	}
+	print "      {"
+	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 "      }"
+	print "    },"
+	# arch
+	print "    TARGET_ARCH_" arch_cnames[feats[1]]
+	print "  },"
+    }
+
+    print "  {{NULL, NULL, {isa_nobit}}, TARGET_ARCH_arm_none}"
+    print "};"
+
     narchs = split (arch_list, archs)
 
     for (n = 1; n <= narchs; n++) {
+	if (archs[n] in arch_opts) {
+	    print "static const struct cpu_arch_extension 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]] ", false,"
+		print "    { " arch_opt_isa[archs[n],opts[opt]] ", isa_nobit }"
+		print "  },"
+	    }
+	    if (archs[n] in arch_optaliases) {
+		naliases = split (arch_optaliases[archs[n]], aliases)
+		for (alias = 1; alias <= naliases; alias++) {
+		    if (! ((archs[n], \
+			    arch_opt_alias[archs[n],aliases[alias]]) in \
+			   arch_opt_isa)) {
+			fatal("Alias " aliases[alias] " target not defined " \
+			      "for architecture " archs[n])
+		    }
+		    equiv=arch_opt_alias[archs[n],aliases[alias]]
+		    print "  {"
+		    print "    \"" aliases[alias] "\", " \
+			arch_opt_remove[archs[n],equiv] ", true, "
+		    print "    { " arch_opt_isa[archs[n],equiv] ", isa_nobit }"
+		    print "  },"
+		}
+	    }
+	    print "  { NULL, false, false, {isa_nobit}}"
+	    print "};\n"
+	} else if (archs[n] in arch_optaliases) {
+	    fatal("Architecture " archs[n] " has option aliases but no options")
+	}
+    }
+
+    print "const arch_option all_architectures[] ="
+    print "{"
+
+    for (n = 1; n <= narchs; n++) {
 	print "  {"
 	if (! (arch_tune_for[archs[n]] in cpu_cnames)) {
 	    fatal("unknown \"tune for\" target " arch_tune_for[archs[n]] \
 		  " for architecture " archs[n])
 	}
-	print "    \"" archs[n] \
-	    "\", TARGET_CPU_" cpu_cnames[arch_tune_for[archs[n]]] ","
-	if (archs[n] in arch_tune_flags) {
-	    print "    (" arch_tune_flags[archs[n]] "),"
-	} else print "    0,"
-	print "    \"" arch_base[archs[n]] "\", BASE_ARCH_" \
-	    arch_base[archs[n]] ","
+	# common.name
+	print "    \"" archs[n] "\","
+	# common.extensions
+	if (archs[n] in arch_opts) {
+	    print "    arch_opttab_" arch_cnames[archs[n]] ","
+	} else print "    NULL,"
+	# common.isa_bits
 	print "    {"
 	print "      " arch_isa[archs[n]] ","
 	print "      isa_nobit"
 	print "    },"
-	print "    NULL"
+	# arch, base_arch
+	print "    \"" arch_base[archs[n]] "\", BASE_ARCH_" \
+	    arch_base[archs[n]] ","
+	# tune_id
+	print "    TARGET_CPU_" cpu_cnames[arch_tune_for[archs[n]]] ","
 	print "  },"
     }
 
-    print "  {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0," \
-	" {isa_nobit}, NULL}"
+    print "  {{NULL, NULL, {isa_nobit}},"
+    print "   NULL, BASE_ARCH_0, TARGET_CPU_arm_none}"
     print "};\n"
 
-    print "const struct arm_fpu_desc all_fpus[] ="
+    print "const arm_fpu_desc all_fpus[] ="
     print "{"
 
     nfpus = split (fpu_list, fpus)
@@ -204,44 +326,6 @@ function gen_data () {
     print "};"
 }
 
-function gen_comm_data () {
-    boilerplate("C")
-
-    print "static const struct arm_arch_core_flag arm_arch_core_flags[] ="
-    print "{"
-
-    ncpus = split (cpu_list, cpus)
-
-    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])
-	}
-	print "    {"
-	print "      " arch_isa[cpu_arch[cpus[n]]] ","
-	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 "    },"
-	print "  },"
-    }
-
-    narchs = split (arch_list, archs)
-
-    for (n = 1; n <= narchs; n++) {
-	print "  {"
-	print "    \"" archs[n] "\","
-	print "    {"
-	print "      " arch_isa[archs[n]] ","
-	print "      isa_nobit"
-	print "    },"
-	print "  },"
-    }
-
-    print "};\n"
-}
-
 function gen_md () {
     boilerplate("md")
 
@@ -309,9 +393,19 @@ function gen_opt () {
 }
 
 function check_cpu (name) {
-    if (name in cpu_cnames) {
-	print cpu_cnames[name]
-    } else print "error"
+    exts = split (name, extensions, "+")
+
+    if (! extensions[1] in cpu_cnames) {
+	return "error"
+    }
+
+    for (n = 2; n <= exts; n++) {
+	if (!((extensions[1], extensions[n]) in cpu_opt_remove)	\
+	    && !((extensions[1], extensions[n]) in cpu_optaliases)) {
+	    return "error"
+	}
+    }
+    return name
 }
 
 function check_fpu (name) {
@@ -321,9 +415,19 @@ function check_fpu (name) {
 }
 
 function check_arch (name) {
-    if (name in arch_isa) {
-	print name
-    } else print "error"
+    exts = split (name, extensions, "+")
+
+    if (! extensions[1] in arch_isa) {
+	return "error"
+    }
+
+    for (n = 2; n <= exts; n++) {
+	if (!((extensions[1], extensions[n]) in arch_opt_remove)	\
+	    && !((extensions[1], extensions[n]) in arch_optaliases)) {
+	    return "error"
+	}
+    }
+    return name
 }
 
 BEGIN {
@@ -382,6 +486,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 +559,45 @@ 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
+}
+
+/^[ 	]*optalias / {
+    name=$2
+    alias=$3
+    if (cpu_name != "") {
+	cpu_optaliases[cpu_name] = cpu_optaliases[cpu_name] " " name
+	cpu_opt_alias[cpu_name,name] = alias
+    } else if (arch_name != "") {
+	arch_optaliases[arch_name] = arch_optaliases[arch_name] " " name
+	arch_opt_alias[arch_name,name] = alias
+    } else fatal("\"optalias\" outside of cpu or arch block")
+    parse_ok = 1
+}
+
 /^[ 	]*costs / {
     if (cpu_name == "") fatal("\"costs\" outside of cpu block")
     cpu_cost[cpu_name] = $2
@@ -489,10 +634,10 @@ END {
 	gen_opt()
     } else if (cmd ~ /^chk(cpu|tune) /) {
 	split (cmd, target)
-	check_cpu(target[2])
+	print check_cpu(target[2])
     } else if (cmd ~ /^chkarch /) {
 	split (cmd, target)
-	check_arch(target[2])
+	print check_arch(target[2])
     } else if (cmd ~ /^chkfpu /) {
 	split (cmd, target)
 	check_fpu(target[2])
diff --git a/gcc/config/arm/t-aprofile b/gcc/config/arm/t-aprofile
index b71cbda..0a36d05 100644
--- a/gcc/config/arm/t-aprofile
+++ b/gcc/config/arm/t-aprofile
@@ -26,145 +26,83 @@
 
 # Arch and FPU variants to build libraries with
 
-MULTI_ARCH_OPTS_A       = march=armv7-a/march=armv7ve/march=armv8-a
-MULTI_ARCH_DIRS_A       = v7-a v7ve v8-a
+MULTI_ARCH_OPTS_A       = march=armv7-a/march=armv7-a+fp/march=armv7-a+simd/march=armv7ve+simd/march=armv8-a/march=armv8-a+simd
+MULTI_ARCH_DIRS_A       = v7-a v7-a+fp v7-a+simd v7ve+simd v8-a v8-a+simd
 
-MULTI_FPU_OPTS_A        = mfpu=vfpv3-d16/mfpu=neon/mfpu=vfpv4-d16/mfpu=neon-vfpv4/mfpu=neon-fp-armv8
-MULTI_FPU_DIRS_A        = fpv3 simdv1 fpv4 simdvfpv4 simdv8
+# ARMv7-A - build nofp, fp-d16 and SIMD variants
 
+MULTILIB_REQUIRED	+= mthumb/march=armv7-a/mfloat-abi=soft
+MULTILIB_REQUIRED	+= mthumb/march=armv7-a+fp/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mthumb/march=armv7-a+fp/mfloat-abi=softfp
+MULTILIB_REQUIRED	+= mthumb/march=armv7-a+simd/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mthumb/march=armv7-a+simd/mfloat-abi=softfp
 
-# Option combinations to build library with
+# ARMv7VE - only build a SIMD (+VFPv4) variant.
+MULTILIB_REQUIRED	+= mthumb/march=armv7ve+simd/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mthumb/march=armv7ve+simd/mfloat-abi=softfp
 
-# Default CPU/Arch (ARM is implicitly included because it uses the default
-# multilib)
-MULTILIB_REQUIRED      += mthumb
+# ARMv8-A - build nofp and SIMD variants.
+MULTILIB_REQUIRED	+= mthumb/march=armv8-a/mfloat-abi=soft
+MULTILIB_REQUIRED	+= mthumb/march=armv8-a+simd/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mthumb/march=armv8-a+simd/mfloat-abi=softfp
 
-# ARMv7-A
-MULTILIB_REQUIRED      += *march=armv7-a
-MULTILIB_REQUIRED      += *march=armv7-a/mfpu=vfpv3-d16/mfloat-abi=*
-MULTILIB_REQUIRED      += *march=armv7-a/mfpu=neon/mfloat-abi=*
+# Matches
 
-# ARMv7VE
-MULTILIB_REQUIRED      += *march=armv7ve
-MULTILIB_REQUIRED      += *march=armv7ve/mfpu=vfpv4-d16/mfloat-abi=*
-MULTILIB_REQUIRED      += *march=armv7ve/mfpu=neon-vfpv4/mfloat-abi=*
+# Arch Matches
+# Map all v7-a FP variants to vfpv3-d16 (+fp)
+MULTILIB_MATCHES	+= $(foreach ARCH, $(filter-out +fp, $(v7_a_nosimd_variants)), \
+			     march?armv7-a+fp=march?armv7-a$(ARCH))
 
-# ARMv8-A
-MULTILIB_REQUIRED      += *march=armv8-a
-MULTILIB_REQUIRED      += *march=armv8-a/mfpu=neon-fp-armv8/mfloat-abi=*
+# Map all v7-a SIMD variants to neon-vfpv3 (+simd)
+MULTILIB_MATCHES	+= $(foreach ARCH, $(filter-out +simd, $(v7_a_simd_variants)), \
+			     march?armv7-a+simd=march?armv7-a$(ARCH))
 
+# Neither FP nor SIMD: map v7ve to v7-a
+MULTILIB_MATCHES	+= march?armv7-a=march?armv7ve
 
-# Matches
+# ARMv7ve FP-only variants: map down to v7-a+fp
+MULTILIB_MATCHES	+= $(foreach ARCH, $(v7ve_nosimd_variants), \
+			     march?armv7-a+fp=march?armv7ve$(ARCH))
 
-# CPU Matches
-MULTILIB_MATCHES       += march?armv7-a=mcpu?marvell-pj4
-MULTILIB_MATCHES       += march?armv7-a=mcpu?generic-armv7-a
-MULTILIB_MATCHES       += march?armv7-a=mcpu?cortex-a8
-MULTILIB_MATCHES       += march?armv7-a=mcpu?cortex-a9
-MULTILIB_MATCHES       += march?armv7-a=mcpu?cortex-a5
-MULTILIB_MATCHES       += march?armv7ve=mcpu?cortex-a7
-MULTILIB_MATCHES       += march?armv7ve=mcpu?cortex-a15
-MULTILIB_MATCHES       += march?armv7ve=mcpu?cortex-a12
-MULTILIB_MATCHES       += march?armv7ve=mcpu?cortex-a17
-MULTILIB_MATCHES       += march?armv7ve=mcpu?cortex-a15.cortex-a7
-MULTILIB_MATCHES       += march?armv7ve=mcpu?cortex-a17.cortex-a7
-MULTILIB_MATCHES       += march?armv8-a=mcpu?cortex-a32
-MULTILIB_MATCHES       += march?armv8-a=mcpu?cortex-a35
-MULTILIB_MATCHES       += march?armv8-a=mcpu?cortex-a53
-MULTILIB_MATCHES       += march?armv8-a=mcpu?cortex-a57
-MULTILIB_MATCHES       += march?armv8-a=mcpu?cortex-a57.cortex-a53
-MULTILIB_MATCHES       += march?armv8-a=mcpu?cortex-a72
-MULTILIB_MATCHES       += march?armv8-a=mcpu?cortex-a72.cortex-a53
-MULTILIB_MATCHES       += march?armv8-a=mcpu?cortex-a73
-MULTILIB_MATCHES       += march?armv8-a=mcpu?cortex-a73.cortex-a35
-MULTILIB_MATCHES       += march?armv8-a=mcpu?cortex-a73.cortex-a53
-MULTILIB_MATCHES       += march?armv8-a=mcpu?exynos-m1
-MULTILIB_MATCHES       += march?armv8-a=mcpu?falkor
-MULTILIB_MATCHES       += march?armv8-a=mcpu?qdf24xx
-MULTILIB_MATCHES       += march?armv8-a=mcpu?xgene1
+# ARMv7ve with SIMD, but SIMD is less capable than the default - map down to v7-a+simd
+MULTILIB_MATCHES	+= $(foreach ARCH, $(v7ve_vfpv3_simd_variants), \
+			     march?armv7-a+simd=march?armv7ve$(ARCH))
 
-# Arch Matches
-MULTILIB_MATCHES       += march?armv8-a=march?armv8-a+crc
-MULTILIB_MATCHES       += march?armv8-a=march?armv8.1-a
-MULTILIB_MATCHES       += march?armv8-a=march?armv8.1-a+crc
-MULTILIB_MATCHES       += march?armv8-a=march?armv8.2-a
-MULTILIB_MATCHES       += march?armv8-a=march?armv8.2-a+fp16
-
-# FPU matches
-MULTILIB_MATCHES       += mfpu?vfpv3-d16=mfpu?vfpv3
-MULTILIB_MATCHES       += mfpu?vfpv3-d16=mfpu?vfpv3-fp16
-MULTILIB_MATCHES       += mfpu?vfpv3-d16=mfpu?vfpv3-d16-fp16
-MULTILIB_MATCHES       += mfpu?neon=mfpu?neon-fp16
-MULTILIB_MATCHES       += mfpu?vfpv4-d16=mfpu?vfpv4
-MULTILIB_MATCHES       += mfpu?vfpv4-d16=mfpu?fpv5-d16
-MULTILIB_MATCHES       += mfpu?vfpv4-d16=mfpu?fp-armv8
-MULTILIB_MATCHES       += mfpu?neon-fp-armv8=mfpu?crypto-neon-fp-armv8
-MULTILIB_MATCHES       += mfpu?vfp=mfpu?vfpv2
-MULTILIB_MATCHES       += mfpu?neon=mfpu?neon-vfpv3
-
-
-# Map all requests for vfpv3 with a later CPU to vfpv3-d16 v7-a.
-# So if new CPUs are added above at the newer architecture levels,
-# do something to map them below here.
-# We take the approach of mapping down to v7-a regardless of what
-# the fp option is if the integer architecture brings things down.
-# This applies to any similar combination at the v7ve and v8-a arch
-# levels.
-
-MULTILIB_REUSE	      += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=march.armv7ve/mfpu.vfpv3-d16/mfloat-abi.hard
-MULTILIB_REUSE	      += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=march.armv7ve/mfpu.vfpv3-d16/mfloat-abi.softfp
-MULTILIB_REUSE	      += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=march.armv8-a/mfpu.vfpv3-d16/mfloat-abi.hard
-MULTILIB_REUSE	      += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=march.armv8-a/mfpu.vfpv3-d16/mfloat-abi.softfp
-MULTILIB_REUSE	      += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=march.armv7-a/mfpu.vfpv4-d16/mfloat-abi.hard
-MULTILIB_REUSE	      += march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=march.armv7-a/mfpu.vfpv4-d16/mfloat-abi.softfp
-
-
-MULTILIB_REUSE	      += march.armv7-a/mfpu.neon/mfloat-abi.hard=march.armv7ve/mfpu.neon/mfloat-abi.hard
-MULTILIB_REUSE	      += march.armv7-a/mfpu.neon/mfloat-abi.softfp=march.armv7ve/mfpu.neon/mfloat-abi.softfp
-MULTILIB_REUSE	      += march.armv7-a/mfpu.neon/mfloat-abi.hard=march.armv8-a/mfpu.neon/mfloat-abi.hard
-MULTILIB_REUSE	      += march.armv7-a/mfpu.neon/mfloat-abi.softfp=march.armv8-a/mfpu.neon/mfloat-abi.softfp
-MULTILIB_REUSE	      += march.armv7-a/mfpu.neon/mfloat-abi.hard=march.armv7-a/mfpu.neon-vfpv4/mfloat-abi.hard
-MULTILIB_REUSE	      += march.armv7-a/mfpu.neon/mfloat-abi.softfp=march.armv7-a/mfpu.neon-vfpv4/mfloat-abi.softfp
-MULTILIB_REUSE	      += march.armv7-a/mfpu.neon/mfloat-abi.hard=march.armv7-a/mfpu.neon-fp-armv8/mfloat-abi.hard
-MULTILIB_REUSE	      += march.armv7-a/mfpu.neon/mfloat-abi.softfp=march.armv7-a/mfpu.neon-fp-armv8/mfloat-abi.softfp
-
-
-MULTILIB_REUSE	      += march.armv7ve/mfpu.vfpv4-d16/mfloat-abi.hard=march.armv8-a/mfpu.vfpv4-d16/mfloat-abi.hard
-MULTILIB_REUSE	      += march.armv7ve/mfpu.vfpv4-d16/mfloat-abi.softfp=march.armv8-a/mfpu.vfpv4-d16/mfloat-abi.softfp
-
-
-MULTILIB_REUSE	      += march.armv7ve/mfpu.neon-vfpv4/mfloat-abi.hard=march.armv8-a/mfpu.neon-vfpv4/mfloat-abi.hard
-MULTILIB_REUSE	      += march.armv7ve/mfpu.neon-vfpv4/mfloat-abi.softfp=march.armv8-a/mfpu.neon-vfpv4/mfloat-abi.softfp
-MULTILIB_REUSE	      += march.armv7ve/mfpu.neon-vfpv4/mfloat-abi.hard=march.armv7ve/mfpu.neon-fp-armv8/mfloat-abi.hard
-MULTILIB_REUSE	      += march.armv7ve/mfpu.neon-vfpv4/mfloat-abi.softfp=march.armv7ve/mfpu.neon-fp-armv8/mfloat-abi.softfp
-
-
-
-# And again for mthumb.
-
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/march.armv7ve/mfpu.vfpv3-d16/mfloat-abi.hard
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/march.armv7ve/mfpu.vfpv3-d16/mfloat-abi.softfp
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.vfpv3-d16/mfloat-abi.hard
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.vfpv3-d16/mfloat-abi.softfp
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/march.armv7-a/mfpu.vfpv4-d16/mfloat-abi.hard
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/march.armv7-a/mfpu.vfpv4-d16/mfloat-abi.softfp
-
-
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.hard=mthumb/march.armv7ve/mfpu.neon/mfloat-abi.hard
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=mthumb/march.armv7ve/mfpu.neon/mfloat-abi.softfp
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.neon/mfloat-abi.hard
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.neon/mfloat-abi.softfp
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.hard=mthumb/march.armv7-a/mfpu.neon-vfpv4/mfloat-abi.hard
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=mthumb/march.armv7-a/mfpu.neon-vfpv4/mfloat-abi.softfp
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.hard=mthumb/march.armv7-a/mfpu.neon-fp-armv8/mfloat-abi.hard
-MULTILIB_REUSE	      += mthumb/march.armv7-a/mfpu.neon/mfloat-abi.softfp=mthumb/march.armv7-a/mfpu.neon-fp-armv8/mfloat-abi.softfp
-
-
-MULTILIB_REUSE	      += mthumb/march.armv7ve/mfpu.vfpv4-d16/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.vfpv4-d16/mfloat-abi.hard
-MULTILIB_REUSE	      += mthumb/march.armv7ve/mfpu.vfpv4-d16/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.vfpv4-d16/mfloat-abi.softfp
-
-
-MULTILIB_REUSE	      += mthumb/march.armv7ve/mfpu.neon-vfpv4/mfloat-abi.hard=mthumb/march.armv8-a/mfpu.neon-vfpv4/mfloat-abi.hard
-MULTILIB_REUSE	      += mthumb/march.armv7ve/mfpu.neon-vfpv4/mfloat-abi.softfp=mthumb/march.armv8-a/mfpu.neon-vfpv4/mfloat-abi.softfp
-MULTILIB_REUSE	      += mthumb/march.armv7ve/mfpu.neon-vfpv4/mfloat-abi.hard=mthumb/march.armv7ve/mfpu.neon-fp-armv8/mfloat-abi.hard
-MULTILIB_REUSE	      += mthumb/march.armv7ve/mfpu.neon-vfpv4/mfloat-abi.softfp=mthumb/march.armv7ve/mfpu.neon-fp-armv8/mfloat-abi.softfp
+# ARMv8 without SIMD: map down to base architecture
+MULTILIB_MATCHES	+= $(foreach ARCH, $(v8_a_nosimd_variants), \
+			     march?armv8-a=march?armv8-a$(ARCH))
+
+# ARMv8 with SIMD: map down to base arch + simd
+MULTILIB_MATCHES	+= march?armv8-a+simd=march?armv8-a+crc+simd \
+			   $(foreach ARCH, $(filter-out +simd, $(v8_a_simd_variants)), \
+			     march?armv8-a+simd=march?armv8-a$(ARCH) \
+			     march?armv8-a+simd=march?armv8-a+crc$(ARCH))
+
+# Baseline v8.1-a: map down to baseline v8-a
+MULTILIB_MATCHES	+= march?armv8-a=march?armv8.1-a
+
+# Map all v8.1-a SIMD variants to v8-a+simd
+MULTILIB_MATCHES	+= $(foreach ARCH, $(v8_1_a_simd_variants), \
+			     march?armv8-a+simd=march?armv8.1-a$(ARCH))
+
+# Baseline v8.2-a: map down to baseline v8-a
+MULTILIB_MATCHES	+= march?armv8-a=march?armv8.2-a
+
+# Map all v8.2-a SIMD variants to v8-a+simd
+MULTILIB_MATCHES	+= $(foreach ARCH, $(v8_2_a_simd_variants), \
+			     march?armv8-a+simd=march?armv8.2-a$(ARCH))
+
+# Use Thumb libraries for everything.
+
+MULTILIB_REUSE		+= mthumb/march.armv7-a/mfloat-abi.soft=marm/march.armv7-a/mfloat-abi.soft
+
+MULTILIB_REUSE		+= mthumb/march.armv8-a/mfloat-abi.soft=marm/march.armv8-a/mfloat-abi.soft
+
+MULTILIB_REUSE		+= $(foreach ABI, hard softfp, \
+			     $(foreach ARCH, armv7-a+fp armv7-a+simd armv7ve+simd armv8-a+simd, \
+			       mthumb/march.$(ARCH)/mfloat-abi.$(ABI)=marm/march.$(ARCH)/mfloat-abi.$(ABI)))
+
+# Softfp but no FP, use the soft-float libraries.
+MULTILIB_REUSE		+= $(foreach MODE, arm thumb, \
+			     $(foreach ARCH, armv7-a armv8-a, \
+			       mthumb/march.$(ARCH)/mfloat-abi.soft=m$(MODE)/march.$(ARCH)/mfloat-abi.softfp))
diff --git a/gcc/config/arm/t-arm-elf b/gcc/config/arm/t-arm-elf
index f3ad3f7..1337841 100644
--- a/gcc/config/arm/t-arm-elf
+++ b/gcc/config/arm/t-arm-elf
@@ -16,75 +16,110 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-MULTILIB_OPTIONS     = marm/mthumb
-MULTILIB_DIRNAMES    = arm thumb
+# Build a very basic set of libraries that should cater for most cases.
+
+# Single-precision floating-point is NOT supported; we don't build a
+# suitable library for that.  Use the rm-profile config in that case.
+
+# PART 1 - Useful groups of options
+
+dp_fpus		:= vfp vfpv2 vfpv3 vfpv3-fp16 vfpv3-d16 vfpv3-d16-fp16 \
+		   neon neon-vfpv3 neon-fp16 vfpv4 neon-vfpv4 vfpv4-d16 \
+		   fpv5-d16 fp-armv8 neon-fp-armv8 crypto-neon-fp-armv8 \
+		   vfp3
+
+sp_fpus		:= vfpv3xd vfpv3xd-fp16  fpv4-sp-d16 fpv5-sp-d16
+
+v7a_fps		:= vfpv3 vfpv3-fp16 vfpv4 simd neon-fp16 neon-vfpv4
+v7ve_fps	:= vfpv3-d16 vfpv3 vfpv3-d16-fp16 vfpv3-fp16 vfpv4 neon \
+		   neon-fp16 simd
+
+# Not all these permutations exist for all architecture variants, but
+# it seems to work ok.
+v8_fps		:= simd fp16 crypto fp16+crypto
+
+# We don't do anything special with these.  Pre-v4t probably doesn't work.
+all_early_nofp	:= armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5t
+
+all_early_arch	:= armv5e armv5tej armv6 armv6j armv6k armv6z armv6kz \
+		   armv6zk armv6t2 iwmmxt iwmmxt2
+
+all_v7_a_r	:= armv7-a armv7ve armv7-r
+
+all_v8_archs	:= armv8-a armv8-a+crc armv8.1-a armv8.2-a
+
+# No floating point variants, require thumb1 softfp
+all_nofp_t	:= armv6-m armv6s-m armv8-m.base
+
+all_nofp_t2	:= armv7-m
+
+all_sp_only	:= armv7e-m armv8-m.main
+
+MULTILIB_OPTIONS     =
+MULTILIB_DIRNAMES    =
 MULTILIB_EXCEPTIONS  = 
 MULTILIB_MATCHES     =
+MULTILIB_REUSE	     =
+
+# PART 2 - multilib build rules
+
+MULTILIB_OPTIONS     += marm/mthumb
+MULTILIB_DIRNAMES    += arm thumb
+
+MULTILIB_OPTIONS     += mfpu=auto
+MULTILIB_DIRNAMES    += autofp
+
+MULTILIB_OPTIONS     += march=armv5te+fp/march=armv7+fp
+MULTILIB_DIRNAMES    += v5te v7
+
+MULTILIB_OPTIONS     += mfloat-abi=hard
+MULTILIB_DIRNAMES    += fpu
+
+# Build a total of 4 library variants (base options plus the following):
+MULTILIB_REQUIRED    += mthumb
+MULTILIB_REQUIRED    += marm/mfpu=auto/march=armv5te+fp/mfloat-abi=hard
+MULTILIB_REQUIRED    += mthumb/mfpu=auto/march=armv7+fp/mfloat-abi=hard
+
+# PART 3 - Match rules
+
+# Map all supported FPUs onto mfpu=auto
+MULTILIB_MATCHES     += $(foreach FPU, $(dp_fpus), \
+			  mfpu?auto=mfpu?$(FPU))
+
+MULTILIB_MATCHES     += march?armv5te+fp=march?armv5te
+
+MULTILIB_MATCHES     += $(foreach ARCH, $(all_early_arch), \
+		          march?armv5te+fp=march?$(ARCH) \
+			  march?armv5te+fp=march?$(ARCH)+fp)
+
+MULTILIB_MATCHES     += march?armv7+fp=march?armv7
+
+MULTILIB_MATCHES     += $(foreach FPARCH, $(v7a_fps), \
+		          march?armv7+fp=march?armv7-a+$(FPARCH))
+
+MULTILIB_MATCHES     += $(foreach FPARCH, $(v7ve_fps), \
+		          march?armv7+fp=march?armv7ve+$(FPARCH))
+
+MULTILIB_MATCHES     += $(foreach ARCH, $(all_v7_a_r), \
+			  march?armv7+fp=march?$(ARCH) \
+			  march?armv7+fp=march?$(ARCH)+fp)
+
+MULTILIB_MATCHES     += $(foreach ARCH, $(all_v8_archs), \
+			  march?armv7+fp=march?$(ARCH) \
+			  $(foreach FPARCH, $(v8_fps), \
+			    march?armv7+fp=march?$(ARCH)+$(FPARCH)))
+
+MULTILIB_MATCHES     += $(foreach ARCH, armv7e-m armv8-m.mainline, \
+			  march?armv7+fp=march?$(ARCH)+fp.dp)
+
+# PART 4 - Reuse rules
 
-#MULTILIB_OPTIONS     += mcpu=fa526/mcpu=fa626/mcpu=fa606te/mcpu=fa626te/mcpu=fmp626/mcpu=fa726te
-#MULTILIB_DIRNAMES    += fa526 fa626 fa606te fa626te fmp626 fa726te
-#MULTILIB_EXCEPTIONS  += *mthumb*/*mcpu=fa526 *mthumb*/*mcpu=fa626
-
-#MULTILIB_OPTIONS      += march=armv7
-#MULTILIB_DIRNAMES     += thumb2
-#MULTILIB_EXCEPTIONS   += march=armv7* marm/*march=armv7*
-#MULTILIB_MATCHES      += march?armv7=march?armv7-a
-#MULTILIB_MATCHES      += march?armv7=march?armv7-r
-#MULTILIB_MATCHES      += march?armv7=march?armv7-m
-#MULTILIB_MATCHES      += march?armv7=mcpu?cortex-a8
-#MULTILIB_MATCHES      += march?armv7=mcpu?cortex-r4
-#MULTILIB_MATCHES      += march?armv7=mcpu?cortex-m3
-
-# Not quite true.  We can support hard-vfp calling in Thumb2, but how do we
-# express that here?  Also, we really need architecture v5e or later
-# (mcrr etc).
-MULTILIB_OPTIONS       += mfloat-abi=hard
-MULTILIB_DIRNAMES      += fpu
-MULTILIB_EXCEPTIONS    += *mthumb/*mfloat-abi=hard*
-#MULTILIB_EXCEPTIONS    += *mcpu=fa526/*mfloat-abi=hard*
-#MULTILIB_EXCEPTIONS    += *mcpu=fa626/*mfloat-abi=hard*
-
-# MULTILIB_OPTIONS    += mcpu=ep9312
-# MULTILIB_DIRNAMES   += ep9312
-# MULTILIB_EXCEPTIONS += *mthumb/*mcpu=ep9312*
-# 	
-# MULTILIB_OPTIONS     += mlittle-endian/mbig-endian
-# MULTILIB_DIRNAMES    += le be
-# MULTILIB_MATCHES     += mbig-endian=mbe mlittle-endian=mle
-# 
-# MULTILIB_OPTIONS    += mfloat-abi=hard/mfloat-abi=soft
-# MULTILIB_DIRNAMES   += fpu soft
-# MULTILIB_EXCEPTIONS += *mthumb/*mfloat-abi=hard*
-# 
-# MULTILIB_OPTIONS    += mno-thumb-interwork/mthumb-interwork
-# MULTILIB_DIRNAMES   += normal interwork
-# 
-# MULTILIB_OPTIONS    += fno-leading-underscore/fleading-underscore
-# MULTILIB_DIRNAMES   += elf under
-# 
-# MULTILIB_OPTIONS    += mcpu=arm7
-# MULTILIB_DIRNAMES   += nofmult
-# MULTILIB_EXCEPTIONS += *mthumb*/*mcpu=arm7*
-# # Note: the multilib_exceptions matches both -mthumb and
-# # -mthumb-interwork
-# #
-# # We have to match all the arm cpu variants which do not have the
-# # multiply instruction and treat them as if the user had specified
-# # -mcpu=arm7.  Note that in the following the ? is interpreted as
-# # an = for the purposes of matching command line options.
-# # FIXME: There ought to be a better way to do this.
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7d
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7di
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm70
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm700
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm700i
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm710
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm710c
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7100
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7500
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm7500fe
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm6
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm60
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm600
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm610
-# MULTILIB_MATCHES    += mcpu?arm7=mcpu?arm620
+MULTILIB_REUSE	     += mthumb=mthumb/mfpu.auto
+MULTILIB_REUSE	     += mthumb=mthumb/mfpu.auto/march.armv5te+fp
+MULTILIB_REUSE	     += mthumb=mthumb/march.armv5te+fp
+MULTILIB_REUSE	     += marm/mfpu.auto/march.armv5te+fp/mfloat-abi.hard=marm/march.armv5te+fp/mfloat-abi.hard
+MULTILIB_REUSE	     += marm/mfpu.auto/march.armv5te+fp/mfloat-abi.hard=march.armv5te+fp/mfloat-abi.hard
+MULTILIB_REUSE	     += marm/mfpu.auto/march.armv5te+fp/mfloat-abi.hard=mfpu.auto/march.armv5te+fp/mfloat-abi.hard
+MULTILIB_REUSE	     += mthumb/mfpu.auto/march.armv7+fp/mfloat-abi.hard=mthumb/march.armv7+fp/mfloat-abi.hard
+MULTILIB_REUSE	     += mthumb/mfpu.auto/march.armv7+fp/mfloat-abi.hard=mfpu.auto/march.armv7+fp/mfloat-abi.hard
+MULTILIB_REUSE	     += mthumb/mfpu.auto/march.armv7+fp/mfloat-abi.hard=march.armv7+fp/mfloat-abi.hard
diff --git a/gcc/config/arm/t-fuchsia b/gcc/config/arm/t-fuchsia
new file mode 100644
index 0000000..18fc518
--- /dev/null
+++ b/gcc/config/arm/t-fuchsia
@@ -0,0 +1,33 @@
+# Copyright (C) 2017 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Reset all the multilib variables.
+MULTILIB_OPTIONS	=
+MULTILIB_DIRNAMES	=
+MULTILIB_EXCEPTIONS	=
+MULTILIB_REUSE		=
+MULTILIB_MATCHES	=
+MULTILIB_REQUIRED	=
+
+# For compatibility with gcc-7 we build the following multilibs
+MULTILIB_OPTIONS	+= marm/mthumb
+MULTILIB_DIRNAMES	+= arm thumb
+
+MULTILIB_OPTIONS	+= mfloat-abi=hard
+MULTILIB_DIRNAMES	+= fpu
+MULTILIB_EXCEPTIONS	+= *mthumb/*mfloat-abi=hard*
diff --git a/gcc/config/arm/t-linux-eabi b/gcc/config/arm/t-linux-eabi
index 117c0eb..c11af7a 100644
--- a/gcc/config/arm/t-linux-eabi
+++ b/gcc/config/arm/t-linux-eabi
@@ -22,6 +22,10 @@
 # MULTILIB_DEFAULTS in linux-elf.h.
 MULTILIB_OPTIONS	=
 MULTILIB_DIRNAMES	=
+MULTILIB_EXCEPTIONS	=
+MULTILIB_REUSE		=
+MULTILIB_MATCHES	=
+MULTILIB_REQUIRED	=
 
 #MULTILIB_OPTIONS     += mcpu=fa606te/mcpu=fa626te/mcpu=fmp626/mcpu=fa726te
 #MULTILIB_DIRNAMES    += fa606te fa626te fmp626 fa726te
diff --git a/gcc/config/arm/t-multilib b/gcc/config/arm/t-multilib
index 642e731..ec4b76d 100644
--- a/gcc/config/arm/t-multilib
+++ b/gcc/config/arm/t-multilib
@@ -29,6 +29,7 @@ MULTILIB_DIRNAMES    =
 MULTILIB_EXCEPTIONS  =
 MULTILIB_MATCHES     =
 MULTILIB_REUSE	     =
+MULTILIB_REQUIRED    =
 
 comma := ,
 tm_multilib_list := $(subst $(comma), ,$(TM_MULTILIB_CONFIG))
@@ -36,6 +37,40 @@ tm_multilib_list := $(subst $(comma), ,$(TM_MULTILIB_CONFIG))
 HAS_APROFILE := $(filter aprofile,$(tm_multilib_list))
 HAS_RMPROFILE := $(filter rmprofile,$(tm_multilib_list))
 
+# Produce the combinatorial list of extensions.  Where there are
+# multiple permutations for a combination, the ordering is the
+# selected by the forward ordering of the original list.  This matches
+# the canonical ordering generated by the canonicalizer in the driver.
+#
+# For example,
+#   $(call all_feat_combs, a b)
+# will produce
+#   +a +a+b +b
+# but will not include
+#   +b+a
+# The rule is recursive and can be called with any (reasonable) list of
+# extensions.
+all_feat_combs	= +$(firstword $(1)) \
+		  $(if $(wordlist 2, $(words $(1)), $(1)), \
+		    $(foreach OPT, \
+		      $(call all_feat_combs, \
+		        $(wordlist 2, $(words $(1)), $(1))), \
+		      +$(firstword $(1))$(OPT) $(OPT)),)
+
+# Variables used.
+all_early_arch		:= armv5e armv5tej armv6 armv6j armv6k armv6z armv6kz \
+			   armv6zk armv6t2 iwmmxt iwmmxt2
+v7_a_nosimd_variants	:= +fp +vfpv3 +vfpv3-d16-fp16 +vfpv3-fp16 +vfpv4-d16 +vfpv4
+v7_a_simd_variants	:= +simd +neon-fp16 +neon-vfpv4
+v7ve_nosimd_variants	:= +vfpv3-d16 +vfpv3 +vfpv3-d16-fp16 +vfpv3-fp16 +fp +vfpv4
+v7ve_vfpv3_simd_variants := +neon +neon-fp16
+v7ve_vfpv4_simd_variants := +simd
+v8_a_nosimd_variants	:= +crc
+v8_a_simd_variants	:= $(call all_feat_combs, simd crypto)
+v8_1_a_simd_variants	:= $(call all_feat_combs, simd crypto)
+v8_2_a_simd_variants	:= $(call all_feat_combs, simd fp16 crypto)
+
+
 ifneq (,$(HAS_APROFILE))
 include $(srcdir)/config/arm/t-aprofile
 endif
@@ -45,25 +80,80 @@ endif
 SEP := $(and $(HAS_APROFILE),$(HAS_RMPROFILE),/)
 
 
-# We have the following hierachy:
-#   ISA: A32 (.) or T16/T32 (thumb)
-#   Architecture: ARMv6-M (v6-m), ARMv7-M (v7-m), ARMv7E-M (v7e-m),
-#                 ARMv7 (v7-ar), ARMv7-A (v7-a), ARMv7VE (v7ve),
-#                 ARMv8-M Baseline (v8-m.base), ARMv8-M Mainline (v8-m.main)
-#                 or ARMv8-A (v8-a).
-#   FPU: VFPv3-D16 (fpv3), NEONv1 (simdv1), FPV4-SP-D16 (fpv4-sp),
-#        VFPv4-D16 (fpv4), NEON-VFPV4 (simdvfpv4), FPV5-SP-D16 (fpv5-sp),
-#        VFPv5-D16 (fpv5), NEON for ARMv8 (simdv8), or None (.).
-#   Float-abi: Soft (.), softfp (softfp), or hard (hard).
+MULTILIB_OPTIONS	+= marm/mthumb
+MULTILIB_DIRNAMES	+= arm thumb
+
+MULTILIB_OPTIONS	+= march=armv5te+fp/march=armv7/march=armv7+fp/$(MULTI_ARCH_OPTS_A)$(SEP)$(MULTI_ARCH_OPTS_RM)
+MULTILIB_DIRNAMES	+= v5te v7 v7+fp $(MULTI_ARCH_DIRS_A) $(MULTI_ARCH_DIRS_RM)
+
+MULTILIB_OPTIONS	+= mfloat-abi=soft/mfloat-abi=softfp/mfloat-abi=hard
+MULTILIB_DIRNAMES	+= nofp softfp hard
+
+MULTILIB_REQUIRED	+= mthumb/mfloat-abi=soft
+MULTILIB_REQUIRED	+= marm/march=armv5te+fp/mfloat-abi=softfp
+MULTILIB_REQUIRED	+= marm/march=armv5te+fp/mfloat-abi=hard
+
+MULTILIB_REQUIRED	+= mthumb/march=armv7/mfloat-abi=soft
+MULTILIB_REQUIRED	+= mthumb/march=armv7+fp/mfloat-abi=softfp
+MULTILIB_REQUIRED	+= mthumb/march=armv7+fp/mfloat-abi=hard
+
+# Map v7-r down onto common v7 code.
+MULTILIB_MATCHES	+= march?armv7=march?armv7-r
+MULTILIB_MATCHES	+= march?armv7=march?armv7-r+idiv
+MULTILIB_MATCHES	+= march?armv7+fp=march?armv7-r+fp
+MULTILIB_MATCHES	+= march?armv7+fp=march?armv7-r+fp+idiv
+
+MULTILIB_MATCHES	+= $(foreach ARCH, $(all_early_arch), \
+			     march?armv5te+fp=march?$(ARCH)+fp)
+
+ifeq (,$(HAS_APROFILE))
+# Map all v7-a
+MULTILIB_MATCHES	+= march?armv7=march?armv7-a
+MULTILIB_MATCHES	+= $(foreach ARCH, $(v7_a_nosimd_variants) $(v7_a_simd_variants), \
+			     march?armv7+fp=march?armv7-a$(ARCH))
+
+MULTILIB_MATCHES	+= march?armv7=march?armv7ve
+
+# ARMv7ve FP/SIMD variants: map down to v7+fp
+MULTILIB_MATCHES	+= $(foreach ARCH, $(v7ve_nosimd_variants) $(v7ve_vfpv3_simd_variants) $(v7ve_vfpv4_simd_variants), \
+			     march?armv7+fp=march?armv7ve$(ARCH))
+
+# ARMv8
+MULTILIB_MATCHES	+= march?armv7=march?armv8-a
+MULTILIB_MATCHES	+= $(foreach ARCH, $(v8_a_nosimd_variants), \
+			     march?armv7=march?armv8-a$(ARCH))
+
+# ARMv8 with SIMD
+MULTILIB_MATCHES	+= march?armv7+fp=march?armv8-a+crc+simd \
+			   $(foreach ARCH, $(v8_a_simd_variants), \
+			     march?armv7+fp=march?armv8-a$(ARCH) \
+			     march?armv7+fp=march?armv8-a+crc$(ARCH))
+
+# Baseline v8.1-a
+MULTILIB_MATCHES	+= march?armv7=march?armv8.1-a
+
+# Map all v8.1-a SIMD variants
+MULTILIB_MATCHES	+= $(foreach ARCH, $(v8_1_a_simd_variants), \
+			     march?armv7+fp=march?armv8.1-a$(ARCH))
+
+# Baseline v8.2-a: map down to baseline v8-a
+MULTILIB_MATCHES	+= march?armv7=march?armv8.2-a
+
+# Map all v8.2-a SIMD variants
+MULTILIB_MATCHES	+= $(foreach ARCH, $(v8_2_a_simd_variants), \
+			     march?armv7+fp=march?armv8.2-a$(ARCH))
+
+# Use Thumb libraries for everything.
 
-MULTILIB_OPTIONS       += mthumb
-MULTILIB_DIRNAMES      += thumb
+MULTILIB_REUSE		+= mthumb/march.armv7/mfloat-abi.soft=marm/march.armv7/mfloat-abi.soft
 
-MULTILIB_OPTIONS       += $(MULTI_ARCH_OPTS_A)$(SEP)$(MULTI_ARCH_OPTS_RM)
-MULTILIB_DIRNAMES      += $(MULTI_ARCH_DIRS_A) $(MULTI_ARCH_DIRS_RM)
+MULTILIB_REUSE		+= $(foreach ABI, hard softfp, \
+			     $(foreach ARCH, armv7+fp, \
+			       mthumb/march.$(ARCH)/mfloat-abi.$(ABI)=marm/march.$(ARCH)/mfloat-abi.$(ABI)))
 
-MULTILIB_OPTIONS       += $(MULTI_FPU_OPTS_A)$(SEP)$(MULTI_FPU_OPTS_RM)
-MULTILIB_DIRNAMES      += $(MULTI_FPU_DIRS_A) $(MULTI_FPU_DIRS_RM)
+# Softfp but no FP, use the soft-float libraries.
+MULTILIB_REUSE		+= $(foreach MODE, arm thumb, \
+			     $(foreach ARCH, armv7, \
+			       mthumb/march.$(ARCH)/mfloat-abi.soft=m$(MODE)/march.$(ARCH)/mfloat-abi.softfp))
 
-MULTILIB_OPTIONS       += mfloat-abi=softfp/mfloat-abi=hard
-MULTILIB_DIRNAMES      += softfp hard
+endif		# Not APROFILE.
\ No newline at end of file
diff --git a/gcc/config/arm/t-phoenix b/gcc/config/arm/t-phoenix
index dea5257..4930ba8 100644
--- a/gcc/config/arm/t-phoenix
+++ b/gcc/config/arm/t-phoenix
@@ -16,14 +16,16 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-MULTILIB_OPTIONS     = marm/mthumb
-MULTILIB_DIRNAMES    = arm thumb
-MULTILIB_EXCEPTIONS  =
-MULTILIB_MATCHES     =
+MULTILIB_OPTIONS	= marm/mthumb
+MULTILIB_DIRNAMES	= arm thumb
+MULTILIB_EXCEPTIONS	=
+MULTILIB_MATCHES	=
+MULTILIB_REUSE		=
+MULTILIB_REQUIRED	=
 
-MULTILIB_OPTIONS     += mfloat-abi=hard
-MULTILIB_DIRNAMES    += fpu
-MULTILIB_MATCHES     += mfloat-abi?hard=mhard-float
+MULTILIB_OPTIONS	+= mfloat-abi=hard
+MULTILIB_DIRNAMES	+= fpu
+MULTILIB_MATCHES	+= mfloat-abi?hard=mhard-float
 
-MULTILIB_OPTIONS     += mno-thumb-interwork/mthumb-interwork
-MULTILIB_DIRNAMES    += normal interwork
+MULTILIB_OPTIONS	+= mno-thumb-interwork/mthumb-interwork
+MULTILIB_DIRNAMES	+= normal interwork
diff --git a/gcc/config/arm/t-rmprofile b/gcc/config/arm/t-rmprofile
index 8cd7351..1ad8eac 100644
--- a/gcc/config/arm/t-rmprofile
+++ b/gcc/config/arm/t-rmprofile
@@ -27,131 +27,42 @@
 
 # Arch and FPU variants to build libraries with
 
-MULTI_ARCH_OPTS_RM      = march=armv6s-m/march=armv7-m/march=armv7e-m/march=armv7/march=armv8-m.base/march=armv8-m.main
-MULTI_ARCH_DIRS_RM      = v6-m v7-m v7e-m v7-ar v8-m.base v8-m.main
+MULTI_ARCH_OPTS_RM	= march=armv6s-m/march=armv7-m/march=armv7e-m/march=armv7e-m+fp/march=armv7e-m+fp.dp/march=armv8-m.base/march=armv8-m.main/march=armv8-m.main+fp/march=armv8-m.main+fp.dp
+MULTI_ARCH_DIRS_RM	= v6-m v7-m v7e-m v7e-m+fp v7e-m+dp v8-m.base v8-m.main v8-m.main+fp v8-m.main+dp
 
-MULTI_FPU_OPTS_RM       = mfpu=vfpv3-d16/mfpu=fpv4-sp-d16/mfpu=fpv5-sp-d16/mfpu=fpv5-d16
-MULTI_FPU_DIRS_RM       = fpv3 fpv4-sp fpv5-sp fpv5
+# Base M-profile (no fp)
+MULTILIB_REQUIRED	+= mthumb/march=armv6s-m/mfloat-abi=soft
+MULTILIB_REQUIRED	+= mthumb/march=armv7-m/mfloat-abi=soft
+MULTILIB_REQUIRED	+= mthumb/march=armv7e-m/mfloat-abi=soft
+MULTILIB_REQUIRED	+= mthumb/march=armv8-m.base/mfloat-abi=soft
+MULTILIB_REQUIRED	+= mthumb/march=armv8-m.main/mfloat-abi=soft
 
+# ARMv7e-M with FP (single and double precision variants)
+MULTILIB_REQUIRED	+= mthumb/march=armv7e-m+fp/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mthumb/march=armv7e-m+fp/mfloat-abi=softfp
+MULTILIB_REQUIRED	+= mthumb/march=armv7e-m+fp.dp/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mthumb/march=armv7e-m+fp.dp/mfloat-abi=softfp
 
-# Option combinations to build library with
+# ARMv8-M with FP (single and double precision variants)
+MULTILIB_REQUIRED	+= mthumb/march=armv8-m.main+fp/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mthumb/march=armv8-m.main+fp/mfloat-abi=softfp
+MULTILIB_REQUIRED	+= mthumb/march=armv8-m.main+fp.dp/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mthumb/march=armv8-m.main+fp.dp/mfloat-abi=softfp
 
-# Default CPU/Arch
-MULTILIB_REQUIRED      += mthumb
-MULTILIB_REQUIRED      += mfloat-abi=hard
 
-# ARMv6-M
-MULTILIB_REQUIRED      += mthumb/march=armv6s-m
-
-# ARMv8-M Baseline
-MULTILIB_REQUIRED      += mthumb/march=armv8-m.base
-
-# ARMv7-M
-MULTILIB_REQUIRED      += mthumb/march=armv7-m
-
-# ARMv7E-M
-MULTILIB_REQUIRED      += mthumb/march=armv7e-m
-MULTILIB_REQUIRED      += mthumb/march=armv7e-m/mfpu=fpv4-sp-d16/mfloat-abi=softfp
-MULTILIB_REQUIRED      += mthumb/march=armv7e-m/mfpu=fpv4-sp-d16/mfloat-abi=hard
-MULTILIB_REQUIRED      += mthumb/march=armv7e-m/mfpu=fpv5-d16/mfloat-abi=softfp
-MULTILIB_REQUIRED      += mthumb/march=armv7e-m/mfpu=fpv5-d16/mfloat-abi=hard
-MULTILIB_REQUIRED      += mthumb/march=armv7e-m/mfpu=fpv5-sp-d16/mfloat-abi=softfp
-MULTILIB_REQUIRED      += mthumb/march=armv7e-m/mfpu=fpv5-sp-d16/mfloat-abi=hard
-
-# ARMv8-M Mainline
-MULTILIB_REQUIRED      += mthumb/march=armv8-m.main
-MULTILIB_REQUIRED      += mthumb/march=armv8-m.main/mfpu=fpv5-d16/mfloat-abi=softfp
-MULTILIB_REQUIRED      += mthumb/march=armv8-m.main/mfpu=fpv5-d16/mfloat-abi=hard
-MULTILIB_REQUIRED      += mthumb/march=armv8-m.main/mfpu=fpv5-sp-d16/mfloat-abi=softfp
-MULTILIB_REQUIRED      += mthumb/march=armv8-m.main/mfpu=fpv5-sp-d16/mfloat-abi=hard
-
-# ARMv7-R as well as ARMv7-A and ARMv8-A if aprofile was not specified
-MULTILIB_REQUIRED      += mthumb/march=armv7
-MULTILIB_REQUIRED      += mthumb/march=armv7/mfpu=vfpv3-d16/mfloat-abi=softfp
-MULTILIB_REQUIRED      += mthumb/march=armv7/mfpu=vfpv3-d16/mfloat-abi=hard
-
-
-# Matches
-
-# CPU Matches
-MULTILIB_MATCHES       += march?armv6s-m=mcpu?cortex-m0
-MULTILIB_MATCHES       += march?armv6s-m=mcpu?cortex-m0.small-multiply
-MULTILIB_MATCHES       += march?armv6s-m=mcpu?cortex-m0plus
-MULTILIB_MATCHES       += march?armv6s-m=mcpu?cortex-m0plus.small-multiply
-MULTILIB_MATCHES       += march?armv6s-m=mcpu?cortex-m1
-MULTILIB_MATCHES       += march?armv6s-m=mcpu?cortex-m1.small-multiply
-MULTILIB_MATCHES       += march?armv7-m=mcpu?cortex-m3
-MULTILIB_MATCHES       += march?armv7e-m=mcpu?cortex-m4
-MULTILIB_MATCHES       += march?armv7e-m=mcpu?cortex-m7
-MULTILIB_MATCHES       += march?armv8-m.base=mcpu?cortex-m23
-MULTILIB_MATCHES       += march?armv8-m.main=mcpu?cortex-m33
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-r4
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-r4f
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-r5
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-r7
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-r8
-MULTILIB_MATCHES       += march?armv7=mcpu?marvell-pj4
-MULTILIB_MATCHES       += march?armv7=mcpu?generic-armv7-a
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a8
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a9
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a5
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a7
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a15
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a12
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a17
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a15.cortex-a7
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a17.cortex-a7
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a32
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a35
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a53
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a57
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a57.cortex-a53
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a72
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a72.cortex-a53
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a73
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a73.cortex-a35
-MULTILIB_MATCHES       += march?armv7=mcpu?cortex-a73.cortex-a53
-MULTILIB_MATCHES       += march?armv7=mcpu?exynos-m1
-MULTILIB_MATCHES       += march?armv7=mcpu?qdf24xx
-MULTILIB_MATCHES       += march?armv7=mcpu?xgene1
 
 # Arch Matches
-MULTILIB_MATCHES       += march?armv6s-m=march?armv6-m
-MULTILIB_MATCHES       += march?armv8-m.main=march?armv8-m.main+dsp
-MULTILIB_MATCHES       += march?armv7=march?armv7-r
-ifeq (,$(HAS_APROFILE))
-MULTILIB_MATCHES       += march?armv7=march?armv7-a
-MULTILIB_MATCHES       += march?armv7=march?armv7ve
-MULTILIB_MATCHES       += march?armv7=march?armv8-a
-MULTILIB_MATCHES       += march?armv7=march?armv8-a+crc
-MULTILIB_MATCHES       += march?armv7=march?armv8.1-a
-MULTILIB_MATCHES       += march?armv7=march?armv8.1-a+crc
-MULTILIB_MATCHES       += march?armv7=march?armv8.2-a
-MULTILIB_MATCHES       += march?armv7=march?armv8.2-a+fp16
-endif
+MULTILIB_MATCHES	+= march?armv6s-m=march?armv6-m
+
+# Map all v8-m.main+dsp FP variants down the the variant without DSP.
+MULTILIB_MATCHES	+= march?armv8-m.main=march?armv8-m.main+dsp \
+			   $(foreach FP, +fp +fp.dp, \
+			     march?armv8-m.main$(FP)=march?armv8-m.main+dsp$(FP))
 
-# FPU matches
-ifeq (,$(HAS_APROFILE))
-MULTILIB_MATCHES       += mfpu?vfpv3-d16=mfpu?vfpv3
-MULTILIB_MATCHES       += mfpu?vfpv3-d16=mfpu?vfpv3-fp16
-MULTILIB_MATCHES       += mfpu?vfpv3-d16=mfpu?vfpv3-d16-fp16
-MULTILIB_MATCHES       += mfpu?vfpv3-d16=mfpu?neon
-MULTILIB_MATCHES       += mfpu?vfpv3-d16=mfpu?neon-fp16
-MULTILIB_MATCHES       += mfpu?vfpv3-d16=mfpu?vfpv4
-MULTILIB_MATCHES       += mfpu?vfpv3-d16=mfpu?vfpv4-d16
-MULTILIB_MATCHES       += mfpu?vfpv3-d16=mfpu?neon-vfpv4
-MULTILIB_MATCHES       += mfpu?fpv5-d16=mfpu?fp-armv8
-MULTILIB_MATCHES       += mfpu?fpv5-d16=mfpu?neon-fp-armv8
-MULTILIB_MATCHES       += mfpu?fpv5-d16=mfpu?crypto-neon-fp-armv8
-endif
+# For single-precision only fpv5, use the base fp libraries
+MULTILIB_MATCHES	+= march?armv7e-m+fp=march?armv7e-m+fpv5
 
+# Softfp but no FP.  Use the soft-float libraries.
+MULTILIB_REUSE		+= $(foreach ARCH, armv6s-m armv7-m armv7e-m armv8-m\.base armv8-m\.main, \
+			     mthumb/march.$(ARCH)/mfloat-abi.soft=mthumb/march.$(ARCH)/mfloat-abi.softfp)
 
-# We map all requests for ARMv7-R or ARMv7-A in ARM mode to Thumb mode and
-# any FPU to VFPv3-d16 if possible.
-MULTILIB_REUSE         += mthumb/march.armv7=march.armv7
-MULTILIB_REUSE         += mthumb/march.armv7/mfpu.vfpv3-d16/mfloat-abi.softfp=march.armv7/mfpu.vfpv3-d16/mfloat-abi.softfp
-MULTILIB_REUSE         += mthumb/march.armv7/mfpu.vfpv3-d16/mfloat-abi.hard=march.armv7/mfpu.vfpv3-d16/mfloat-abi.hard
-MULTILIB_REUSE         += mthumb/march.armv7/mfpu.vfpv3-d16/mfloat-abi.softfp=march.armv7/mfpu.fpv5-d16/mfloat-abi.softfp
-MULTILIB_REUSE         += mthumb/march.armv7/mfpu.vfpv3-d16/mfloat-abi.hard=march.armv7/mfpu.fpv5-d16/mfloat-abi.hard
-MULTILIB_REUSE         += mthumb/march.armv7/mfpu.vfpv3-d16/mfloat-abi.softfp=mthumb/march.armv7/mfpu.fpv5-d16/mfloat-abi.softfp
-MULTILIB_REUSE         += mthumb/march.armv7/mfpu.vfpv3-d16/mfloat-abi.hard=mthumb/march.armv7/mfpu.fpv5-d16/mfloat-abi.hard
diff --git a/gcc/config/arm/t-rtems b/gcc/config/arm/t-rtems
index 026a589..c073786 100644
--- a/gcc/config/arm/t-rtems
+++ b/gcc/config/arm/t-rtems
@@ -1,22 +1,37 @@
 # Custom RTEMS multilibs for ARM
 
-MULTILIB_OPTIONS  = mbig-endian mthumb march=armv6-m/march=armv7-a/march=armv7-r/march=armv7-m/mcpu=cortex-m7 mfpu=neon/mfpu=vfp/mfpu=vfpv3-d16/mfpu=fpv4-sp-d16/mfpu=fpv5-d16 mfloat-abi=hard
-MULTILIB_DIRNAMES = eb thumb armv6-m armv7-a armv7-r armv7-m cortex-m7 neon vfp vfpv3-d16 fpv4-sp-d16 fpv5-d16 hard
+# Reset all MULTILIB variables
+
+MULTILIB_OPTIONS	=
+MULTILIB_DIRNAMES	=
+MULTILIB_EXCEPTIONS	=
+MULTILIB_REUSE		=
+MULTILIB_MATCHES	=
+MULTILIB_REQUIRED	=
 
 # Enumeration of multilibs
 
-MULTILIB_EXCEPTIONS =
-
-MULTILIB_REQUIRED =
-MULTILIB_REQUIRED += mbig-endian/mthumb/march=armv7-r/mfpu=vfpv3-d16/mfloat-abi=hard
-MULTILIB_REQUIRED += mbig-endian/mthumb/march=armv7-r
-MULTILIB_REQUIRED += mfpu=vfp/mfloat-abi=hard
-MULTILIB_REQUIRED += mthumb/march=armv6-m
-MULTILIB_REQUIRED += mthumb/march=armv7-a/mfpu=neon/mfloat-abi=hard
-MULTILIB_REQUIRED += mthumb/march=armv7-a
-MULTILIB_REQUIRED += mthumb/march=armv7-r/mfpu=vfpv3-d16/mfloat-abi=hard
-MULTILIB_REQUIRED += mthumb/march=armv7-r
-MULTILIB_REQUIRED += mthumb/march=armv7-m/mfpu=fpv4-sp-d16/mfloat-abi=hard
-MULTILIB_REQUIRED += mthumb/mcpu=cortex-m7/mfpu=fpv5-d16/mfloat-abi=hard
-MULTILIB_REQUIRED += mthumb/march=armv7-m
-MULTILIB_REQUIRED += mthumb
+MULTILIB_OPTIONS	+= mbig-endian
+MULTILIB_DIRNAMES	+= eb
+
+MULTILIB_OPTIONS	+= mthumb
+MULTILIB_DIRNAMES	+= thumb
+
+MULTILIB_OPTIONS	+= march=armv5te+fp/march=armv6-m/march=armv7-a/march=armv7-a+simd/march=armv7-r/march=armv7-r+fp/march=armv7-m/march=armv7e-m+fp/march=armv7e-m+fp.dp
+MULTILIB_DIRNAMES	+= armv5te+fp       armv6-m       armv7-a       armv7-a+simd       armv7-r       armv7-r+fp       armv7-m       armv7e-m+fp        armv7e-m+fp.dp
+
+MULTILIB_OPTIONS	+= mfloat-abi=hard
+MULTILIB_DIRNAMES	+= hard
+
+MULTILIB_REQUIRED	+= mbig-endian/mthumb/march=armv7-r+fp/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mbig-endian/mthumb/march=armv7-r
+MULTILIB_REQUIRED	+= march=armv5te+fp/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mthumb/march=armv6-m
+MULTILIB_REQUIRED	+= mthumb/march=armv7-a+simd/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mthumb/march=armv7-a
+MULTILIB_REQUIRED	+= mthumb/march=armv7-r+fp/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mthumb/march=armv7-r
+MULTILIB_REQUIRED	+= mthumb/march=armv7e-m+fp/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mthumb/march=armv7e-m+fp.dp/mfloat-abi=hard
+MULTILIB_REQUIRED	+= mthumb/march=armv7-m
+MULTILIB_REQUIRED	+= mthumb
diff --git a/gcc/config/arm/t-symbian b/gcc/config/arm/t-symbian
index bc10b58..003651e 100644
--- a/gcc/config/arm/t-symbian
+++ b/gcc/config/arm/t-symbian
@@ -22,5 +22,35 @@ EXTRA_HEADERS += $(srcdir)/ginclude/unwind-arm-common.h
 # multilib for those without -- using the soft-float ABI in both
 # cases.  Symbian OS object should be compiled with interworking
 # enabled, so there are no separate thumb-mode libraries.
-MULTILIB_OPTIONS     = mfloat-abi=softfp
-MULTILIB_DIRNAMES    = softfp
+
+# Reset all the multilib variables.
+MULTILIB_OPTIONS	=
+MULTILIB_DIRNAMES	=
+MULTILIB_EXCEPTIONS	=
+MULTILIB_REUSE		=
+MULTILIB_MATCHES	=
+MULTILIB_REQUIRED	=
+
+MULTILIB_OPTIONS	+= march=armv5te+fp
+MULTILIB_DIRNAMES	+= v5te
+
+MULTILIB_OPTIONS	+= mfloat-abi=softfp
+MULTILIB_DIRNAMES	+= softfp
+
+MULTLILIB_REQUIRED	+= march=armv5te+fp/mfloat-abi=softfp
+
+MULTILIB_MATCHES	+= $(foreach ARCH, $(all_early_arch), \
+			     march?armv5te+fp=march?$(ARCH)+fp)
+
+MULTILIB_MATCHES	+= $(foreach FPARCH, $(v7a_fps), \
+		             march?armv5te+fp=march?armv7-a+$(FPARCH))
+
+MULTILIB_MATCHES	+= $(foreach FPARCH, $(v7ve_fps), \
+		             march?armv5te+fp=march?armv7ve+$(FPARCH))
+
+MULTILIB_MATCHES	+= $(foreach ARCH, $(all_v7_a_r), \
+			     march?armv5te+fp=march?$(ARCH)+fp)
+
+MULTILIB_MATCHES	+= $(foreach ARCH, $(all_v8_archs), \
+			     $(foreach FPARCH, $(v8_fps), \
+			       march?armv5te+fp=march?$(ARCH)+$(FPARCH)))
diff --git a/gcc/config/arm/vxworks.h b/gcc/config/arm/vxworks.h
index 107863b..9af37c7 100644
--- a/gcc/config/arm/vxworks.h
+++ b/gcc/config/arm/vxworks.h
@@ -92,8 +92,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 /* There is no default multilib.  */
 #undef MULTILIB_DEFAULTS
 
-#define FPUTYPE_DEFAULT "vfp"
-
 #undef FUNCTION_PROFILER
 #define FUNCTION_PROFILER VXWORKS_FUNCTION_PROFILER
 
diff --git a/gcc/doc/fragments.texi b/gcc/doc/fragments.texi
index d68be7a..6aef553 100644
--- a/gcc/doc/fragments.texi
+++ b/gcc/doc/fragments.texi
@@ -160,10 +160,12 @@ A reuse rule is comprised of two parts connected by equality sign.  The left
 part is the option set used to build multilib and the right part is the option
 set that will reuse this multilib.  Both parts should only use options
 specified in @code{MULTILIB_OPTIONS} and the equality signs found in options
-name should be replaced with periods.  The order of options in the left part
-matters and should be same with those specified in @code{MULTILIB_REQUIRED} or
-aligned with the order in @code{MULTILIB_OPTIONS}.  There is no such limitation
-for options in the right part as we don't build multilib from them.
+name should be replaced with periods.  An explicit period in the rule can be
+escaped by preceding it with a backslash.  The order of options in the left
+part matters and should be same with those specified in
+@code{MULTILIB_REQUIRED} or aligned with the order in @code{MULTILIB_OPTIONS}.
+There is no such limitation for options in the right part as we don't build
+multilib from them.
 
 @code{MULTILIB_REUSE} is different from @code{MULTILIB_MATCHES} in that it
 sets up relations between two option sets rather than two options.  Here is an
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4a83a3e..a23ba6f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -15138,48 +15138,291 @@ the default for all standard configurations.
 Generate code for a processor running in big-endian mode; the default is
 to compile code for a little-endian processor.
 
-@item -march=@var{name}
+@item -march=@var{name@r{[}+extension@dots{}@r{]}}
 @opindex march
 This specifies the name of the target ARM architecture.  GCC uses this
 name to determine what kind of instructions it can emit when generating
 assembly code.  This option can be used in conjunction with or instead
-of the @option{-mcpu=} option.  Permissible names are: @samp{armv2},
-@samp{armv2a}, @samp{armv3}, @samp{armv3m}, @samp{armv4}, @samp{armv4t},
-@samp{armv5}, @samp{armv5e}, @samp{armv5t}, @samp{armv5te},
-@samp{armv6}, @samp{armv6-m}, @samp{armv6j}, @samp{armv6k},
-@samp{armv6kz}, @samp{armv6s-m},
-@samp{armv6t2}, @samp{armv6z}, @samp{armv6zk},
-@samp{armv7}, @samp{armv7-a}, @samp{armv7-m}, @samp{armv7-r}, @samp{armv7e-m},
-@samp{armv7ve}, @samp{armv8-a}, @samp{armv8-a+crc}, @samp{armv8.1-a},
-@samp{armv8.1-a+crc}, @samp{armv8-m.base}, @samp{armv8-m.main},
-@samp{armv8-m.main+dsp}, @samp{iwmmxt}, @samp{iwmmxt2}.
+of the @option{-mcpu=} option.
+
+Permissible names are:
+@samp{armv4t},
+@samp{armv5t}, @samp{armv5te},
+@samp{armv6}, @samp{armv6j}, @samp{armv6k}, @samp{armv6kz}, @samp{armv6t2},
+@samp{armv6z}, @samp{armv6zk},
+@samp{armv7}, @samp{armv7-a}, @samp{armv7ve}, 
+@samp{armv8-a}, @samp{armv8.1-a}, @samp{armv8.2-a},
+@samp{armv7-r},
+@samp{armv6-m}, @samp{armv6s-m},
+@samp{armv7-m}, @samp{armv7e-m},
+@samp{armv8-m.base}, @samp{armv8-m.main},
+@samp{iwmmxt} and @samp{iwmmxt2}.
+
+Additionally, the following architectures, which lack support for the
+Thumb exection state, are recognized but support is deprecated:
+@samp{armv2}, @samp{armv2a}, @samp{armv3}, @samp{armv3m},
+@samp{armv4}, @samp{armv5} and @samp{armv5e}.
+
+Many of the architectures support extensions.  These can be added by
+appending @samp{+@var{extension}} to the architecture name.  Extension
+options are processed in order and capabilities accumulate.  An extension
+will also enable any necessary base extensions
+upon which it depends.  For example, the @samp{+crypto} extension
+will always enable the @samp{+simd} extension.  The exception to the
+additive construction is for extensions that are prefixed with
+@samp{+no@dots{}}: these extensions disable the specified option and
+any other extensions that may depend on the presence of that
+extension.
 
-Architecture revisions older than @samp{armv4t} are deprecated.
+For example, @samp{-march=armv7-a+simd+nofp+vfpv4} is equivalent to
+writing @samp{-march=armv7-a+vfpv4} since the @samp{+simd} option is
+entirely disabled by the @samp{+nofp} option that follows it.
 
-@option{-march=armv6s-m} is the @samp{armv6-m} architecture with support for
-the (now mandatory) SVC instruction.
+Most extension names are generically named, but have an effect that is
+dependent upon the architecture to which it is applied.  For example,
+the @samp{+simd} option can be applied to both @samp{armv7-a} and
+@samp{armv8-a} architectures, but will enable the original ARMv7
+Advanced SIMD (Neon) extensions for @samp{armv7-a} and the ARMv8-a
+variant for @samp{armv8-a}.
 
-@option{-march=armv6zk} is an alias for @samp{armv6kz}, existing for backwards
-compatibility.
+The table below lists the supported extensions for each architecture.
+Architectures not mentioned do not support any extensions.
 
-@option{-march=armv7ve} is the @samp{armv7-a} architecture with virtualization
-extensions.
+@table @samp
+@item  armv5e
+@itemx armv5te
+@itemx armv6
+@itemx armv6j
+@itemx armv6k
+@itemx armv6kz
+@itemx armv6t2
+@itemx armv6z
+@itemx armv6zk
+@table @samp
+@item +fp
+The VFPv2 floating-point instructions.  The extension @samp{+vfpv2} can be
+used as an alias for this extension.
 
-@option{-march=armv8-a+crc} enables code generation for the ARMv8-A
-architecture together with the optional CRC32 extensions.
+@item +nofp
+Disable the floating-point instructions.
+@end table
 
-@option{-march=armv8.1-a} enables compiler support for the ARMv8.1-A
-architecture.  This also enables the features provided by
-@option{-march=armv8-a+crc}.
+@item armv7
+The common subset of the ARMv7-A, ARMv7-R and ARMv7-M architectures.
+@table @samp
+@item +fp
+The VFPv3 floating-point instructions, with 16 double-precision
+registers.  The extension @samp{+vfpv3-d16} can be used as an alias
+for this extension.  Note that floating-point is not supported by the
+base ARMv7-M architecture, but is compatible with both the ARMv7-A and
+ARMv7-R architectures.
+
+@item +nofp
+Disable the floating-point instructions.
+@end table
 
-@option{-march=armv8.2-a} enables compiler support for the ARMv8.2-A
-architecture.  This also enables the features provided by
-@option{-march=armv8.1-a}.
+@item armv7-a
+@table @samp
+@item +fp
+The VFPv3 floating-point instructions, with 16 double-precision
+registers.  The extension @samp{+vfpv3-d16} can be used as an alias
+for this extension.
+
+@item +simd
+The Advanced SIMD (Neon) v1 and the VFPv3 floating-point instructions.
+The extensions @samp{+neon} and @samp{+neon-vfpv3} can be used as aliases
+for this extension.
+
+@item +vfpv3
+The VFPv3 floating-point instructions, with 32 double-precision
+registers.
+
+@item +vfpv3-d16-fp16
+The VFPv3 floating-point instructions, with 16 double-precision
+registers and the half-precision floating-point conversion operations.
 
-@option{-march=armv8.2-a+fp16} enables compiler support for the
-ARMv8.2-A architecture with the optional FP16 instructions extension.
-This also enables the features provided by @option{-march=armv8.1-a}
-and implies @option{-mfp16-format=ieee}.
+@item +vfpv3-fp16
+The VFPv3 floating-point instructions, with 32 double-precision
+registers and the half-precision floating-point conversion operations.
+
+@item +vfpv4-d16
+The VFPv4 floating-point instructions, with 16 double-precision
+registers.
+
+@item +vfpv4
+The VFPv4 floating-point instructions, with 32 double-precision
+registers.
+
+@item +neon-fp16
+The Advanced SIMD (Neon) v1 and the VFPv3 floating-point instructions, with
+the half-precision floating-point conversion operations.
+
+@item +neon-vfpv4
+The Advanced SIMD (Neon) v2 and the VFPv4 floating-point instructions.
+
+@item +nosimd
+Disable the Advanced SIMD instructions (does not disable floating point).
+
+@item +nofp
+Disable the floating-point and Advanced SIMD instructions.
+@end table
+
+@item armv7ve
+The extended version of the ARMv7-A architecture with support for
+virtualization.
+@table @samp
+@item +fp
+The VFPv4 floating-point instructions, with 16 double-precision registers.
+The extension @samp{+vfpv4-d16} can be used as an alias for this extension.
+
+@item +simd
+The Advanced SIMD (Neon) v2 and the VFPv4 floating-point instructions.  The
+extension @samp{+neon-vfpv4} can be used as an alias for this extension.
+
+@item +vfpv3-d16
+The VFPv3 floating-point instructions, with 16 double-precision
+registers.
+
+@item +vfpv3
+The VFPv3 floating-point instructions, with 32 double-precision
+registers.
+
+@item +vfpv3-d16-fp16
+The VFPv3 floating-point instructions, with 16 double-precision
+registers and the half-precision floating-point conversion operations.
+
+@item +vfpv3-fp16
+The VFPv3 floating-point instructions, with 32 double-precision
+registers and the half-precision floating-point conversion operations.
+
+@item +vfpv4-d16
+The VFPv4 floating-point instructions, with 16 double-precision
+registers.
+
+@item +vfpv4
+The VFPv4 floating-point instructions, with 32 double-precision
+registers.
+
+@item +neon
+The Advanced SIMD (Neon) v1 and the VFPv3 floating-point instructions.
+The extension @samp{+neon-vfpv3} can be used as an alias for this extension.
+
+@item +neon-fp16
+The Advanced SIMD (Neon) v1 and the VFPv3 floating-point instructions, with
+the half-precision floating-point conversion operations.
+
+@item +nosimd
+Disable the Advanced SIMD instructions (does not disable floating point).
+
+@item +nofp
+Disable the floating-point and Advanced SIMD instructions.
+@end table
+
+@item armv8-a
+@table @samp
+@item +crc
+The Cyclic Redundancy Check (CRC) instructions.
+@item +simd
+The ARMv8 Advanced SIMD and floating-point instructions.
+@item +crypto
+The cryptographic instructions.
+@item +nocrypto
+Disable the cryptographic isntructions.
+@item +nofp
+Disable the floating-point, Advanced SIMD and cryptographic instructions.
+@end table
+
+@item armv8.1-a
+@table @samp
+@item +simd
+The ARMv8.1 Advanced SIMD and floating-point instructions.
+
+@item +crypto
+The cryptographic instructions.  This also enables the Advanced SIMD and
+floating-point instructions.
+
+@item +nocrypto
+Disable the cryptographic isntructions.
+
+@item +nofp
+Disable the floating-point, Advanced SIMD and cryptographic instructions.
+@end table
+
+@item armv8.2-a
+@table @samp
+@item +fp16
+The half-precision floating-point data processing instructions.
+This also enables the Advanced SIMD and floating-point instructions.
+
+@item +simd
+The ARMv8.1 Advanced SIMD and floating-point instructions.
+
+@item +crypto
+The cryptographic instructions.  This also enables the Advanced SIMD and
+floating-point instructions.
+
+@item +nocrypto
+Disable the cryptographic extension.
+
+@item +nofp
+Disable the floating-point, Advanced SIMD and cryptographic instructions.
+@end table
+
+@item armv7-r
+@table @samp
+@item +fp.sp
+The single-precision VFPv3 floating-point instructions.  The extension
+@samp{+vfpv3xd} can be used as an alias for this extension.
+
+@item +fp
+The VFPv3 floating-point instructions with 16 double-precision registers.
+The extension +vfpv3-d16 can be used as an alias for this extension.
+
+@item +nofp
+Disable the floating-point extension.
+
+@item +idiv
+The ARM-state integer division instructions.
+
+@item +noidiv
+Disable the ARM-state integer division extension.
+@end table
+
+@item armv7e-m
+@table @samp
+@item +fp
+The single-precision VFPv4 floating-point instructions.
+
+@item +fpv5
+The single-precision FPv5 floating-point instructions.
+
+@item +fp.dp
+The single- and double-precision FPv5 floating-point instructions.
+
+@item +nofp
+Disable the floating-point extensions.
+@end table
+
+@item  armv8-m.main
+@table @samp
+@item +dsp
+The DSP instructions.
+
+@item +nodsp
+Disable the DSP extension.
+
+@item +fp
+The single-precision floating-point instructions.
+
+@item +fp.dp
+The single- and double-precision floating-point instructions.
+
+@item +nofp
+Disable the floating-point extension.
+
+@end table
+
+@end table
 
 @option{-march=native} causes the compiler to auto-detect the architecture
 of the build computer.  At present, this feature is only supported on
@@ -15247,12 +15490,15 @@ processors, balancing between optimizations that benefit some CPUs in the
 range, and avoiding performance pitfalls of other CPUs.  The effects of
 this option may change in future GCC versions as CPU models come and go.
 
+@option{-mtune} permits the same extension options as @option{-mcpu}, but
+the extension options do not affect the tuning of the generated code.
+
 @option{-mtune=native} causes the compiler to auto-detect the CPU
 of the build computer.  At present, this feature is only supported on
 GNU/Linux, and not all architectures are recognized.  If the auto-detect is
 unsuccessful the option has no effect.
 
-@item -mcpu=@var{name}
+@item -mcpu=@var{name@r{[}+extension@dots{}@r{]}}
 @opindex mcpu
 This specifies the name of the target ARM processor.  GCC uses this name
 to derive the name of the target ARM architecture (as if specified
@@ -15261,9 +15507,62 @@ performance (as if specified by @option{-mtune}).  Where this option
 is used in conjunction with @option{-march} or @option{-mtune},
 those options take precedence over the appropriate part of this option.
 
+Many of the supported CPUs implement optional architectural
+extensions.  Where this is so the architectural extensions are
+normally enabled by default.  If implementations that lack the
+extension exist, then the extension syntax can be used to disable
+those extensions that have been omitted.  For floating-point and
+Advanced SIMD (Neon) instructions, the settings of the options
+@option{-mfloat-abi} and @option{-mfpu} must also be considered:
+floating-point and Advanced SIMD instructions will only be used if
+@option{-mfloat-abi} is not set to @samp{soft}; and any setting of
+@option{-mfpu} other than @samp{auto} will override the available
+floating-point and SIMD extension instructions.
+
+For example, @samp{cortex-a9} can be found in three major
+configurations: integer only, with just a floating-point unit or with
+floating-point and Advanced SIMD.  The default is to enable all the
+instructions, but the extensions @samp{+nosimd} and @samp{+nofp} can
+be used to disable just the SIMD or both the SIMD and floating-point
+instructions respectively.
+
 Permissible names for this option are the same as those for
 @option{-mtune}.
 
+The following extension options are common to the listed CPUs:
+
+@table @samp
+@item  +nofp
+Disables the floating-point instructions on @samp{arm9e},
+@samp{arm946e-s}, @samp{arm966e-s}, @samp{arm968e-s}, @samp{arm10e},
+@samp{arm1020e}, @samp{arm1022e}, @samp{arm926ej-s},
+@samp{arm1026ej-s}, @samp{cortex-r5}, @samp{cortex-r7}, @samp{cortex-r8},
+@samp{cortex-m4}, @samp{cortex-m7} and @samp{cortex-m33}.
+Disables the floating-point and SIMD instructions on
+@samp{generic-armv7-a}, @samp{cortex-a5}, @samp{cortex-a7},
+@samp{cortex-a8}, @samp{cortex-a9}, @samp{cortex-a12},
+@samp{cortex-a15}, @samp{cortex-a17}, @samp{cortex-a15.cortex-a7},
+@samp{cortex-a17.cortex-a7}, @samp{cortex-a32}, @samp{cortex-a35}
+and @samp{cortex-a53}.
+
+@item +nofp.dp
+Disables the double-precision component of the floating-point instructions
+on @samp{cortex-r5} and @samp{cortex-m7}.
+
+@item +nosimd
+Disables the SIMD (but not floating-point) instructions on
+@samp{generic-armv7-a}, @samp{cortex-a5}, @samp{cortex-a7}
+and @samp{cortex-a9}.
+@end table
+
+Additionally the @samp{generic-armv7-a} pseudo target defaults to
+VFPv3 with 16 double-precision registers.  It supports the following
+extension options: @samp{vfpv3-d16}, @samp{vfpv3},
+@samp{vfpv3-d16-fp16}, @samp{vfpv3-fp16}, @samp{vfpv4-d16},
+@samp{vfpv4}, @samp{neon}, @samp{neon-vfpv3}, @samp{neon-fp16},
+@samp{neon-vfpv4}.  The meanings are the same as for the extensions to
+@option{-march=armv7-a}.
+
 @option{-mcpu=generic-@var{arch}} is also permissible, and is
 equivalent to @option{-march=@var{arch} -mtune=generic-@var{arch}}.
 See @option{-mtune} for more information.
@@ -15276,7 +15575,8 @@ is unsuccessful the option has no effect.
 @item -mfpu=@var{name}
 @opindex mfpu
 This specifies what floating-point hardware (or hardware emulation) is
-available on the target.  Permissible names are: @samp{vfpv2}, @samp{vfpv3},
+available on the target.  Permissible names are: @samp{auto}, @samp{vfpv2},
+@samp{vfpv3},
 @samp{vfpv3-fp16}, @samp{vfpv3-d16}, @samp{vfpv3-d16-fp16}, @samp{vfpv3xd},
 @samp{vfpv3xd-fp16}, @samp{neon-vfpv3}, @samp{neon-fp16}, @samp{vfpv4},
 @samp{vfpv4-d16}, @samp{fpv4-sp-d16}, @samp{neon-vfpv4},
@@ -15285,11 +15585,12 @@ available on the target.  Permissible names are: @samp{vfpv2}, @samp{vfpv3},
 Note that @samp{neon} is an alias for @samp{neon-vfpv3} and @samp{vfp}
 is an alias for @samp{vfpv2}.
 
-If @option{-msoft-float} is specified this specifies the format of
-floating-point values.
+The setting @samp{auto} is the default and is special.  It causes the
+compiler to select the floating-point and Advanced SIMD instructions
+based on the settings of @option{-mcpu} and @option{-march}.
 
 If the selected floating-point hardware includes the NEON extension
-(e.g. @option{-mfpu}=@samp{neon}), note that floating-point
+(e.g. @option{-mfpu=neon}), note that floating-point
 operations are not generated by GCC's auto-vectorization pass unless
 @option{-funsafe-math-optimizations} is also specified.  This is
 because NEON hardware does not fully implement the IEEE 754 standard for
diff --git a/gcc/genmultilib b/gcc/genmultilib
index 2501f54..c8bcdf3 100644
--- a/gcc/genmultilib
+++ b/gcc/genmultilib
@@ -466,8 +466,8 @@ echo "static const char *const multilib_reuse_raw[] = {"
 for rrule in ${multilib_reuse}; do
   # The left part of the rule are the options we used to build multilib.
   # The right part of the rule are the options that can reuse this multilib.
-  combo=`echo ${rrule} | sed -e 's/=.*$//' -e 's/\./=/g'`
-  copts=`echo ${rrule} | sed -e 's/^.*=//' -e 's/\./=/g'`
+  combo=`echo ${rrule} | sed -e 's/=.*$//' -e 's/\([^\\]\)\./\1=/g' -e 's/\\\././g'`
+  copts=`echo ${rrule} | sed -e 's/^.*=//' -e 's/\([^\\]\)\./\1=/g' -e 's/\\\././g'`
   # The variable ${combinations} are the option combinations we will build
   # multilib from.  If the combination in the left part of reuse rule isn't
   # in this variable, it means no multilib will be built for current reuse
diff --git a/gcc/testsuite/gcc.dg/pr59418.c b/gcc/testsuite/gcc.dg/pr59418.c
index 12999aa..4b54ef2 100644
--- a/gcc/testsuite/gcc.dg/pr59418.c
+++ b/gcc/testsuite/gcc.dg/pr59418.c
@@ -3,7 +3,7 @@
 
 /* { dg-do compile } */
 /* { dg-options "-Os -g" } */
-/* { dg-options "-march=armv7-a -mfloat-abi=hard -Os -g" { target { arm*-*-* && { ! arm_thumb1 } } } } */
+/* { dg-options "-march=armv7-a+fp -mfloat-abi=hard -Os -g" { target { arm*-*-* && { ! arm_thumb1 } } } } */
 
 extern int printf (const char *__format, ...);
 double bar (const char *, int);
diff --git a/gcc/testsuite/gcc.target/arm/multilib.exp b/gcc/testsuite/gcc.target/arm/multilib.exp
new file mode 100644
index 0000000..8e9226a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/multilib.exp
@@ -0,0 +1,685 @@
+# Copyright (C) 2017 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+load_lib gcc-dg.exp
+
+dg-init
+
+if { [board_info [target_info name] exists multilib_flags] 
+     && [regexp {(-marm|-mthumb|-march=.*|-mcpu=.*|-mfpu=.*|-mfloat=abi=.*)\y} [board_info [target_info name] multilib_flags]] } {
+	
+    # Multilib flags override anything we can apply to a test, so
+    # skip if any of the above options are set there.
+    verbose "skipping multilib tests due to multilib_flags setting" 1
+    return
+}
+
+# We don't want to run this test multiple times in a parallel make check.
+if ![gcc_parallel_test_run_p options] {
+    return
+}
+gcc_parallel_test_enable 0
+
+proc multilib_config {profile} {
+    return [check_configured_with [join [list {with-multilib-list=([^ ]+,)?} $profile {(,[^ ]+)?}] ""]]
+}
+
+proc check_multi_dir { gcc_opts multi_dir } {
+    global tool
+
+    set gcc_output [${tool}_target_compile "--print-multi-directory $gcc_opts" "" "none" ""]
+    if { [string match "$multi_dir\n" $gcc_output] } {
+	pass "multilibdir $gcc_opts $multi_dir"
+    } else {
+	fail "multilibdir $gcc_opts $multi_dir"
+    }
+}
+
+if {[multilib_config "aprofile"] } {
+    foreach {opts dir} {
+        {-mcpu=cortex-a8 -mfloat-abi=soft} "thumb/v7-a/nofp"
+        {-mcpu=cortex-a8 -mfloat-abi=softfp} "thumb/v7-a+simd/softfp"
+        {-mcpu=cortex-a8 -mfloat-abi=hard} "thumb/v7-a+simd/hard"
+        {-mcpu=cortex-a15} "thumb/v7-a/nofp"
+        {-mcpu=cortex-a15 -mfloat-abi=hard} "thumb/v7ve+simd/hard"
+        {-mcpu=cortex-a15 -marm -mfloat-abi=hard} "thumb/v7ve+simd/hard"
+        {-mcpu=cortex-a15 -mthumb -mfloat-abi=hard} "thumb/v7ve+simd/hard"
+        {-mcpu=cortex-a7+nosimd -mfloat-abi=hard} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a7+nofp -mfloat-abi=softfp} "thumb/v7-a/nofp"
+	{-mcpu=generic-armv7-a+vfpv4 -mfloat-abi=softfp} "thumb/v7-a+fp/softfp"
+	{-march=armv7ve+vfpv3 -mfloat-abi=hard} "thumb/v7-a+fp/hard"
+	{-march=armv7ve -mfloat-abi=softfp -mfpu=neon} "thumb/v7-a+simd/softfp"
+	{-march=armv7ve -mfloat-abi=softfp -mfpu=neon-vfpv4} "thumb/v7ve+simd/softfp"
+	{-march=armv7ve -mfloat-abi=softfp -mfpu=vfpv4} "thumb/v7-a+fp/softfp"
+	{-march=armv8-a+crc+simd -mfloat-abi=soft} "thumb/v8-a/nofp"
+	{-march=armv8-a+crc+simd -mfloat-abi=softfp} "thumb/v8-a+simd/softfp"
+	{-march=armv8.1-a+crypto -mfloat-abi=soft} "thumb/v8-a/nofp"
+	{-march=armv8.1-a+crypto -mfloat-abi=softfp} "thumb/v8-a+simd/softfp"
+	{-march=armv8.2-a+crypto -mfloat-abi=soft} "thumb/v8-a/nofp"
+	{-march=armv8.2-a+simd+crypto -mfloat-abi=softfp} "thumb/v8-a+simd/softfp"
+	{-march=armv8.2-a+simd+crypto+nofp -mfloat-abi=softfp} "thumb/v8-a/nofp"
+	{-march=armv8.2-a+simd+nofp+crypto -mfloat-abi=softfp} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a53+crypto -mfloat-abi=hard} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a53+nofp -mfloat-abi=softfp} "thumb/v8-a/nofp"
+	{-march=armv8-a+crc -mfloat-abi=hard -mfpu=vfp} "thumb/v8-a+simd/hard"
+	{-march=armv8-a+crc+simd -mfloat-abi=soft -mfpu=neon} "thumb/v8-a/nofp"
+	{-mcpu=cortex-a8 -mfpu=vfpv3-d16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a5 -mfpu=vfpv3-d16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a9 -mfpu=vfpv3-d16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a7 -mfpu=vfpv3-d16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a15 -mfpu=vfpv3-d16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a53 -mfpu=vfpv3-d16 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a5 -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a9 -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a7 -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a15 -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a53 -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=vfpv3 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a5 -mfpu=vfpv3 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a7 -mfpu=vfpv3 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a15 -mfpu=vfpv3 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a53 -mfpu=vfpv3 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=vfpv4-d16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a5 -mfpu=vfpv4-d16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a9 -mfpu=vfpv4-d16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a7 -mfpu=vfpv4-d16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a15 -mfpu=vfpv4-d16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a53 -mfpu=vfpv4-d16 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=vfpv4 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a5 -mfpu=vfpv4 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a9 -mfpu=vfpv4 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a7 -mfpu=vfpv4 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a15 -mfpu=vfpv4 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a53 -mfpu=vfpv4 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a5 -mfpu=neon -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a9 -mfpu=neon -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a7 -mfpu=neon -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a15 -mfpu=neon -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a53 -mfpu=neon -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=neon-vfpv4 -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a5 -mfpu=neon-vfpv4 -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a9 -mfpu=neon-vfpv4 -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -marm} "thumb/v7ve+simd/hard"
+	{-mcpu=cortex-a15 -mfpu=neon-vfpv4 -mfloat-abi=hard -marm} "thumb/v7ve+simd/hard"
+	{-mcpu=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=fp-armv8 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a5 -mfpu=fp-armv8 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a9 -mfpu=fp-armv8 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a7 -mfpu=fp-armv8 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a15 -mfpu=fp-armv8 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a53 -mfpu=fp-armv8 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=neon-fp-armv8 -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a5 -mfpu=neon-fp-armv8 -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a9 -mfpu=neon-fp-armv8 -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a7 -mfpu=neon-fp-armv8 -mfloat-abi=hard -marm} "thumb/v7ve+simd/hard"
+	{-mcpu=cortex-a15 -mfpu=neon-fp-armv8 -mfloat-abi=hard -marm} "thumb/v7ve+simd/hard"
+	{-mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=vfpv3-d16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a5 -mfpu=vfpv3-d16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a9 -mfpu=vfpv3-d16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a7 -mfpu=vfpv3-d16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a15 -mfpu=vfpv3-d16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a53 -mfpu=vfpv3-d16 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a5 -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a9 -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a7 -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a15 -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a53 -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=vfpv3 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a5 -mfpu=vfpv3 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a7 -mfpu=vfpv3 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a15 -mfpu=vfpv3 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a53 -mfpu=vfpv3 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=vfpv4-d16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a5 -mfpu=vfpv4-d16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a9 -mfpu=vfpv4-d16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a7 -mfpu=vfpv4-d16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a15 -mfpu=vfpv4-d16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a53 -mfpu=vfpv4-d16 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=vfpv4 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a5 -mfpu=vfpv4 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a9 -mfpu=vfpv4 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a7 -mfpu=vfpv4 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a15 -mfpu=vfpv4 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a53 -mfpu=vfpv4 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a5 -mfpu=neon -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a7 -mfpu=neon -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a15 -mfpu=neon -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a53 -mfpu=neon -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=neon-vfpv4 -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a5 -mfpu=neon-vfpv4 -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a9 -mfpu=neon-vfpv4 -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=softfp -marm} "thumb/v7ve+simd/softfp"
+	{-mcpu=cortex-a15 -mfpu=neon-vfpv4 -mfloat-abi=softfp -marm} "thumb/v7ve+simd/softfp"
+	{-mcpu=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=fp-armv8 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a5 -mfpu=fp-armv8 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a9 -mfpu=fp-armv8 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a7 -mfpu=fp-armv8 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a15 -mfpu=fp-armv8 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a53 -mfpu=fp-armv8 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=neon-fp-armv8 -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a5 -mfpu=neon-fp-armv8 -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a9 -mfpu=neon-fp-armv8 -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a7 -mfpu=neon-fp-armv8 -mfloat-abi=softfp -marm} "thumb/v7ve+simd/softfp"
+	{-mcpu=cortex-a15 -mfpu=neon-fp-armv8 -mfloat-abi=softfp -marm} "thumb/v7ve+simd/softfp"
+	{-mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-march=armv8-a -mfpu=vfpv3-d16 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-march=armv8-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-march=armv8-a -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-march=armv8-a -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-march=armv8-a -mfpu=vfpv3 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=vfpv3 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-march=armv8-a -mfpu=vfpv3 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=vfpv4-d16 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-march=armv8-a -mfpu=vfpv4-d16 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=vfpv4-d16 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-march=armv8-a -mfpu=vfpv4-d16 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=vfpv4 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-march=armv8-a -mfpu=vfpv4 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=vfpv4 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-march=armv8-a -mfpu=vfpv4 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=neon -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-march=armv8-a -mfpu=neon -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=neon -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-march=armv8-a -mfpu=neon -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-march=armv8-a -mfpu=neon-vfpv4 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-march=armv8-a -mfpu=neon-vfpv4 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=fp-armv8 -mfloat-abi=hard -marm} "thumb/v7-a+fp/hard"
+	{-march=armv8-a -mfpu=fp-armv8 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=fp-armv8 -mfloat-abi=softfp -marm} "thumb/v7-a+fp/softfp"
+	{-march=armv8-a -mfpu=fp-armv8 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=neon-fp-armv8 -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-march=armv8-a -mfpu=neon-fp-armv8 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=neon-fp-armv8 -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-march=armv8-a -mfpu=neon-fp-armv8 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=crypto-neon-fp-armv8 -mfloat-abi=hard -marm} "thumb/v7-a+simd/hard"
+	{-march=armv8-a -mfpu=crypto-neon-fp-armv8 -mfloat-abi=hard -marm} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp -marm} "thumb/v7-a+simd/softfp"
+	{-march=armv8-a -mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp -marm} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=vfpv3-d16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a5 -mfpu=vfpv3-d16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a9 -mfpu=vfpv3-d16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a7 -mfpu=vfpv3-d16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a15 -mfpu=vfpv3-d16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a53 -mfpu=vfpv3-d16 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a5 -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a9 -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a7 -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a15 -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a53 -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=vfpv3 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a5 -mfpu=vfpv3 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a7 -mfpu=vfpv3 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a15 -mfpu=vfpv3 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a53 -mfpu=vfpv3 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=vfpv4-d16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a5 -mfpu=vfpv4-d16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a9 -mfpu=vfpv4-d16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a7 -mfpu=vfpv4-d16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a15 -mfpu=vfpv4-d16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a53 -mfpu=vfpv4-d16 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=vfpv4 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a5 -mfpu=vfpv4 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a9 -mfpu=vfpv4 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a7 -mfpu=vfpv4 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a15 -mfpu=vfpv4 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a53 -mfpu=vfpv4 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a5 -mfpu=neon -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a9 -mfpu=neon -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a7 -mfpu=neon -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a15 -mfpu=neon -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a53 -mfpu=neon -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=neon-vfpv4 -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a5 -mfpu=neon-vfpv4 -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a9 -mfpu=neon-vfpv4 -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -mthumb} "thumb/v7ve+simd/hard"
+	{-mcpu=cortex-a15 -mfpu=neon-vfpv4 -mfloat-abi=hard -mthumb} "thumb/v7ve+simd/hard"
+	{-mcpu=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a5 -mfpu=fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a9 -mfpu=fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a7 -mfpu=fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a15 -mfpu=fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-mcpu=cortex-a53 -mfpu=fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=neon-fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a5 -mfpu=neon-fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a9 -mfpu=neon-fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-mcpu=cortex-a7 -mfpu=neon-fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v7ve+simd/hard"
+	{-mcpu=cortex-a15 -mfpu=neon-fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v7ve+simd/hard"
+	{-mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-mcpu=cortex-a8 -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a5 -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a9 -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a7 -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a15 -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a53 -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a5 -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a9 -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a7 -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a15 -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a53 -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=vfpv3 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a5 -mfpu=vfpv3 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a7 -mfpu=vfpv3 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a15 -mfpu=vfpv3 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a53 -mfpu=vfpv3 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=vfpv4-d16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a5 -mfpu=vfpv4-d16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a9 -mfpu=vfpv4-d16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a7 -mfpu=vfpv4-d16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a15 -mfpu=vfpv4-d16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a53 -mfpu=vfpv4-d16 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a5 -mfpu=vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a9 -mfpu=vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a7 -mfpu=vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a15 -mfpu=vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a53 -mfpu=vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a5 -mfpu=neon -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a7 -mfpu=neon -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a15 -mfpu=neon -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a53 -mfpu=neon -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=neon-vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a5 -mfpu=neon-vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a9 -mfpu=neon-vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v7ve+simd/softfp"
+	{-mcpu=cortex-a15 -mfpu=neon-vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v7ve+simd/softfp"
+	{-mcpu=cortex-a53 -mfpu=neon-vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a5 -mfpu=fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a9 -mfpu=fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a7 -mfpu=fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a15 -mfpu=fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-mcpu=cortex-a53 -mfpu=fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-mcpu=cortex-a8 -mfpu=neon-fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a5 -mfpu=neon-fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a9 -mfpu=neon-fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-mcpu=cortex-a7 -mfpu=neon-fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7ve+simd/softfp"
+	{-mcpu=cortex-a15 -mfpu=neon-fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7ve+simd/softfp"
+	{-mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-march=armv8-a -mfpu=vfpv3-d16 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-march=armv8-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-march=armv8-a -mfpu=vfpv3-d16-fp16 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-march=armv8-a -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-march=armv8-a -mfpu=vfpv3 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=vfpv3 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-march=armv8-a -mfpu=vfpv3 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=vfpv4-d16 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-march=armv8-a -mfpu=vfpv4-d16 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=vfpv4-d16 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-march=armv8-a -mfpu=vfpv4-d16 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=vfpv4 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-march=armv8-a -mfpu=vfpv4 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-march=armv8-a -mfpu=vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=neon -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-march=armv8-a -mfpu=neon -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=neon -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-march=armv8-a -mfpu=neon -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-march=armv8-a -mfpu=neon-vfpv4 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-march=armv8-a -mfpu=neon-vfpv4 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v7-a+fp/hard"
+	{-march=armv8-a -mfpu=fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7-a+fp/softfp"
+	{-march=armv8-a -mfpu=fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=neon-fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-march=armv8-a -mfpu=neon-fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=neon-fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-march=armv8-a -mfpu=neon-fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+	{-march=armv7-a -mfpu=crypto-neon-fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v7-a+simd/hard"
+	{-march=armv8-a -mfpu=crypto-neon-fp-armv8 -mfloat-abi=hard -mthumb} "thumb/v8-a+simd/hard"
+	{-march=armv7-a -mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v7-a+simd/softfp"
+	{-march=armv8-a -mfpu=crypto-neon-fp-armv8 -mfloat-abi=softfp -mthumb} "thumb/v8-a+simd/softfp"
+    } {
+	check_multi_dir $opts $dir
+    }
+}
+if {[multilib_config "rmprofile"] } {
+    foreach {opts dir} {
+	{-mcpu=cortex-m0 -mfpu=auto -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m1 -mfpu=auto -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m3 -mfpu=auto -mfloat-abi=soft} "thumb/v7-m/nofp"
+	{-mcpu=cortex-m4 -mfpu=auto -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m7 -mfpu=auto -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m23 -mfpu=auto -mfloat-abi=soft} "thumb/v8-m.base/nofp"
+	{-mcpu=cortex-m33 -mfpu=auto -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=auto -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m0 -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m1 -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m3 -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v7-m/nofp"
+	{-mcpu=cortex-m4 -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m7 -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m23 -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v8-m.base/nofp"
+	{-mcpu=cortex-m33 -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m0 -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m1 -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m3 -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v7-m/nofp"
+	{-mcpu=cortex-m4 -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m7 -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m23 -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v8-m.base/nofp"
+	{-mcpu=cortex-m33 -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m0 -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m1 -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m3 -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v7-m/nofp"
+	{-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m7 -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m23 -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v8-m.base/nofp"
+	{-mcpu=cortex-m33 -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m0 -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m1 -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m3 -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v7-m/nofp"
+	{-mcpu=cortex-m4 -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m23 -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v8-m.base/nofp"
+	{-mcpu=cortex-m33 -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m0 -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m1 -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m3 -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v7-m/nofp"
+	{-mcpu=cortex-m4 -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m23 -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v8-m.base/nofp"
+	{-mcpu=cortex-m33 -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-mcpu=cortex-m4 -mfpu=auto -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m7 -mfpu=auto -mfloat-abi=hard} "thumb/v7e-m+dp/hard"
+	{-mcpu=cortex-m33 -mfpu=auto -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=auto -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m4 -mfpu=vfpv3xd -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m7 -mfpu=vfpv3xd -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m33 -mfpu=vfpv3xd -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=vfpv3xd -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m4 -mfpu=vfpv3xd-fp16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m7 -mfpu=vfpv3xd-fp16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m33 -mfpu=vfpv3xd-fp16 -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=vfpv3xd-fp16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m7 -mfpu=fpv4-sp-d16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m33 -mfpu=fpv4-sp-d16 -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=fpv4-sp-d16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m4 -mfpu=fpv5-sp-d16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m33 -mfpu=fpv5-sp-d16 -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=fpv5-sp-d16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-mcpu=cortex-m4 -mfpu=fpv5-d16 -mfloat-abi=hard} "thumb/v7e-m+dp/hard"
+	{-mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard} "thumb/v7e-m+dp/hard"
+	{-mcpu=cortex-m33 -mfpu=fpv5-d16 -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=fpv5-d16 -mfloat-abi=hard} "thumb/v7e-m+dp/hard"
+	{-mcpu=cortex-m0 -mfpu=auto -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m1 -mfpu=auto -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m3 -mfpu=auto -mfloat-abi=softfp} "thumb/v7-m/nofp"
+	{-mcpu=cortex-m4 -mfpu=auto -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m7 -mfpu=auto -mfloat-abi=softfp} "thumb/v7e-m+dp/softfp"
+	{-mcpu=cortex-m23 -mfpu=auto -mfloat-abi=softfp} "thumb/v8-m.base/nofp"
+	{-mcpu=cortex-m33 -mfpu=auto -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=auto -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m0 -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m1 -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m3 -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v7-m/nofp"
+	{-mcpu=cortex-m4 -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m7 -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m23 -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v8-m.base/nofp"
+	{-mcpu=cortex-m33 -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m0 -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m1 -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m3 -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v7-m/nofp"
+	{-mcpu=cortex-m4 -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m7 -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m23 -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v8-m.base/nofp"
+	{-mcpu=cortex-m33 -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m0 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m1 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m3 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v7-m/nofp"
+	{-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m7 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m23 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.base/nofp"
+	{-mcpu=cortex-m33 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m0 -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m1 -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m3 -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v7-m/nofp"
+	{-mcpu=cortex-m4 -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m23 -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.base/nofp"
+	{-mcpu=cortex-m33 -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-mcpu=cortex-m0 -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m1 -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-mcpu=cortex-m3 -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v7-m/nofp"
+	{-mcpu=cortex-m4 -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v7e-m+dp/softfp"
+	{-mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v7e-m+dp/softfp"
+	{-mcpu=cortex-m23 -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v8-m.base/nofp"
+	{-mcpu=cortex-m33 -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-mcpu=cortex-m7+nofp.dp -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v7e-m+dp/softfp"
+	{-march=armv6-m -mfpu=auto -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-march=armv7-m -mfpu=auto -mfloat-abi=soft} "thumb/v7-m/nofp"
+	{-march=armv7e-m -mfpu=auto -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv8-m.base -mfpu=auto -mfloat-abi=soft} "thumb/v8-m.base/nofp"
+	{-march=armv8-m.main -mfpu=auto -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv7e-m+fp -mfpu=auto -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv7e-m+fp.dp -mfpu=auto -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv8-m.main+fp -mfpu=auto -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp.dp -mfpu=auto -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp+dsp -mfpu=auto -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=auto -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv6-m -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-march=armv7-m -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v7-m/nofp"
+	{-march=armv7e-m -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv8-m.base -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v8-m.base/nofp"
+	{-march=armv8-m.main -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv7e-m+fp -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv7e-m+fp.dp -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv8-m.main+fp -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp.dp -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp+dsp -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=vfpv3xd -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv6-m -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-march=armv7-m -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v7-m/nofp"
+	{-march=armv7e-m -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv8-m.base -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v8-m.base/nofp"
+	{-march=armv8-m.main -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv7e-m+fp -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv7e-m+fp.dp -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv8-m.main+fp -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp.dp -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp+dsp -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=vfpv3xd-fp16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv6-m -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-march=armv7-m -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v7-m/nofp"
+	{-march=armv7e-m -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv8-m.base -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v8-m.base/nofp"
+	{-march=armv8-m.main -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv7e-m+fp -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv7e-m+fp.dp -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv8-m.main+fp -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp.dp -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp+dsp -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=fpv4-sp-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv6-m -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-march=armv7-m -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v7-m/nofp"
+	{-march=armv7e-m -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv8-m.base -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v8-m.base/nofp"
+	{-march=armv8-m.main -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv7e-m+fp -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv7e-m+fp.dp -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv8-m.main+fp -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp.dp -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp+dsp -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=fpv5-sp-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv6-m -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v6-m/nofp"
+	{-march=armv7-m -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v7-m/nofp"
+	{-march=armv7e-m -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv8-m.base -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v8-m.base/nofp"
+	{-march=armv8-m.main -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv7e-m+fp -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv7e-m+fp.dp -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v7e-m/nofp"
+	{-march=armv8-m.main+fp -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp.dp -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp+dsp -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=fpv5-d16 -mfloat-abi=soft} "thumb/v8-m.main/nofp"
+	{-march=armv7e-m+fp -mfpu=auto -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-march=armv7e-m+fp.dp -mfpu=auto -mfloat-abi=hard} "thumb/v7e-m+dp/hard"
+	{-march=armv8-m.main+fp -mfpu=auto -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv8-m.main+fp.dp -mfpu=auto -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv8-m.main+fp+dsp -mfpu=auto -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=auto -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv7e-m -mfpu=vfpv3xd -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-march=armv8-m.main -mfpu=vfpv3xd -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv7e-m+fp -mfpu=vfpv3xd -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-march=armv7e-m+fp.dp -mfpu=vfpv3xd -mfloat-abi=hard} "thumb/v7e-m+dp/hard"
+	{-march=armv8-m.main+fp -mfpu=vfpv3xd -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv8-m.main+fp.dp -mfpu=vfpv3xd -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv8-m.main+fp+dsp -mfpu=vfpv3xd -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=vfpv3xd -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv7e-m -mfpu=vfpv3xd-fp16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-march=armv8-m.main -mfpu=vfpv3xd-fp16 -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv7e-m+fp -mfpu=vfpv3xd-fp16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-march=armv7e-m+fp.dp -mfpu=vfpv3xd-fp16 -mfloat-abi=hard} "thumb/v7e-m+dp/hard"
+	{-march=armv8-m.main+fp -mfpu=vfpv3xd-fp16 -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv8-m.main+fp.dp -mfpu=vfpv3xd-fp16 -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv8-m.main+fp+dsp -mfpu=vfpv3xd-fp16 -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=vfpv3xd-fp16 -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv7e-m -mfpu=fpv4-sp-d16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-march=armv8-m.main -mfpu=fpv4-sp-d16 -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv7e-m+fp -mfpu=fpv4-sp-d16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-march=armv7e-m+fp.dp -mfpu=fpv4-sp-d16 -mfloat-abi=hard} "thumb/v7e-m+dp/hard"
+	{-march=armv8-m.main+fp -mfpu=fpv4-sp-d16 -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv8-m.main+fp.dp -mfpu=fpv4-sp-d16 -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv8-m.main+fp+dsp -mfpu=fpv4-sp-d16 -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=fpv4-sp-d16 -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv7e-m -mfpu=fpv5-sp-d16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-march=armv8-m.main -mfpu=fpv5-sp-d16 -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv7e-m+fp -mfpu=fpv5-sp-d16 -mfloat-abi=hard} "thumb/v7e-m+fp/hard"
+	{-march=armv7e-m+fp.dp -mfpu=fpv5-sp-d16 -mfloat-abi=hard} "thumb/v7e-m+dp/hard"
+	{-march=armv8-m.main+fp -mfpu=fpv5-sp-d16 -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv8-m.main+fp.dp -mfpu=fpv5-sp-d16 -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv8-m.main+fp+dsp -mfpu=fpv5-sp-d16 -mfloat-abi=hard} "thumb/v8-m.main+fp/hard"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=fpv5-sp-d16 -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv7e-m -mfpu=fpv5-d16 -mfloat-abi=hard} "thumb/v7e-m+dp/hard"
+	{-march=armv8-m.main -mfpu=fpv5-d16 -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv7e-m+fp -mfpu=fpv5-d16 -mfloat-abi=hard} "thumb/v7e-m+dp/hard"
+	{-march=armv7e-m+fp.dp -mfpu=fpv5-d16 -mfloat-abi=hard} "thumb/v7e-m+dp/hard"
+	{-march=armv8-m.main+fp -mfpu=fpv5-d16 -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv8-m.main+fp.dp -mfpu=fpv5-d16 -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv8-m.main+fp+dsp -mfpu=fpv5-d16 -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=fpv5-d16 -mfloat-abi=hard} "thumb/v8-m.main+dp/hard"
+	{-march=armv6-m -mfpu=auto -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-march=armv7-m -mfpu=auto -mfloat-abi=softfp} "thumb/v7-m/nofp"
+	{-march=armv7e-m -mfpu=auto -mfloat-abi=softfp} "thumb/v7e-m/nofp"
+	{-march=armv8-m.base -mfpu=auto -mfloat-abi=softfp} "thumb/v8-m.base/nofp"
+	{-march=armv8-m.main -mfpu=auto -mfloat-abi=softfp} "thumb/v8-m.main/nofp"
+	{-march=armv7e-m+fp -mfpu=auto -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-march=armv7e-m+fp.dp -mfpu=auto -mfloat-abi=softfp} "thumb/v7e-m+dp/softfp"
+	{-march=armv8-m.main+fp -mfpu=auto -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv8-m.main+fp.dp -mfpu=auto -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv8-m.main+fp+dsp -mfpu=auto -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=auto -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv6-m -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-march=armv7-m -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v7-m/nofp"
+	{-march=armv7e-m -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-march=armv8-m.base -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v8-m.base/nofp"
+	{-march=armv8-m.main -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv7e-m+fp -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-march=armv7e-m+fp.dp -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v7e-m+dp/softfp"
+	{-march=armv8-m.main+fp -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv8-m.main+fp.dp -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv8-m.main+fp+dsp -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=vfpv3xd -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv6-m -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-march=armv7-m -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v7-m/nofp"
+	{-march=armv7e-m -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-march=armv8-m.base -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v8-m.base/nofp"
+	{-march=armv8-m.main -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv7e-m+fp -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-march=armv7e-m+fp.dp -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v7e-m+dp/softfp"
+	{-march=armv8-m.main+fp -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv8-m.main+fp.dp -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv8-m.main+fp+dsp -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=vfpv3xd-fp16 -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv6-m -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-march=armv7-m -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v7-m/nofp"
+	{-march=armv7e-m -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-march=armv8-m.base -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.base/nofp"
+	{-march=armv8-m.main -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv7e-m+fp -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-march=armv7e-m+fp.dp -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v7e-m+dp/softfp"
+	{-march=armv8-m.main+fp -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv8-m.main+fp.dp -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv8-m.main+fp+dsp -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=fpv4-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv6-m -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-march=armv7-m -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v7-m/nofp"
+	{-march=armv7e-m -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-march=armv8-m.base -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.base/nofp"
+	{-march=armv8-m.main -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv7e-m+fp -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v7e-m+fp/softfp"
+	{-march=armv7e-m+fp.dp -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v7e-m+dp/softfp"
+	{-march=armv8-m.main+fp -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv8-m.main+fp.dp -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv8-m.main+fp+dsp -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.main+fp/softfp"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=fpv5-sp-d16 -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv6-m -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v6-m/nofp"
+	{-march=armv7-m -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v7-m/nofp"
+	{-march=armv7e-m -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v7e-m+dp/softfp"
+	{-march=armv8-m.base -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v8-m.base/nofp"
+	{-march=armv8-m.main -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv7e-m+fp -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v7e-m+dp/softfp"
+	{-march=armv7e-m+fp.dp -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v7e-m+dp/softfp"
+	{-march=armv8-m.main+fp -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv8-m.main+fp.dp -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv8-m.main+fp+dsp -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+	{-march=armv8-m.main+fp.dp+dsp -mfpu=fpv5-d16 -mfloat-abi=softfp} "thumb/v8-m.main+dp/softfp"
+    } {
+	check_multi_dir $opts $dir
+    }
+}
+
+gcc_parallel_test_enable 1
+
diff --git a/gcc/testsuite/gcc.target/arm/neon-thumb2-move.c b/gcc/testsuite/gcc.target/arm/neon-thumb2-move.c
index 9cf86dd..d8c6748 100644
--- a/gcc/testsuite/gcc.target/arm/neon-thumb2-move.c
+++ b/gcc/testsuite/gcc.target/arm/neon-thumb2-move.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target arm_neon_ok } */
 /* { dg-require-effective-target arm_thumb2_ok } */
-/* { dg-options "-O2 -mthumb -march=armv7-a" } */
+/* { dg-options "-O2 -mthumb" } */
 /* { dg-add-options arm_neon } */
 /* { dg-prune-output "switch .* conflicts with" } */
 
diff --git a/gcc/testsuite/gcc.target/arm/pr51915.c b/gcc/testsuite/gcc.target/arm/pr51915.c
index 144d522..f9ed305 100644
--- a/gcc/testsuite/gcc.target/arm/pr51915.c
+++ b/gcc/testsuite/gcc.target/arm/pr51915.c
@@ -2,7 +2,7 @@
 /* { dg-do compile } */
 /* { dg-skip-if "no support for hard-float VFP ABI" { arm_thumb1 } { "-march=*" } { "" } } */
 /* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
-/* { dg-options "-march=armv7-a -mfloat-abi=hard -O2" } */
+/* { dg-options "-march=armv7-a+fp -mfloat-abi=hard -O2" } */
 
 struct S { int s1; void *s2; };
 struct T { struct S t1; unsigned long long t2; };
diff --git a/gcc/testsuite/gcc.target/arm/pr52006.c b/gcc/testsuite/gcc.target/arm/pr52006.c
index c274449..dbbcfe0 100644
--- a/gcc/testsuite/gcc.target/arm/pr52006.c
+++ b/gcc/testsuite/gcc.target/arm/pr52006.c
@@ -2,7 +2,7 @@
 /* { dg-do compile } */
 /* { dg-skip-if "avoid conflicts with multilib flags" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
 /* { dg-skip-if "no support for hard-float VFP ABI" { arm_thumb1 } { "-march=*" } { "" } } */
-/* { dg-options "-march=armv7-a -mfloat-abi=hard -O2 -fPIC" } */
+/* { dg-options "-march=armv7-a+fp -mfloat-abi=hard -O2 -fPIC" } */
 
 unsigned long a;
 static int b;
diff --git a/gcc/testsuite/gcc.target/arm/pr53187.c b/gcc/testsuite/gcc.target/arm/pr53187.c
index b40dbbb..5fbc52c 100644
--- a/gcc/testsuite/gcc.target/arm/pr53187.c
+++ b/gcc/testsuite/gcc.target/arm/pr53187.c
@@ -2,7 +2,7 @@
 /* { dg-do compile } */
 /* { dg-skip-if "no support for hard-float VFP ABI" { arm_thumb1 } { "-march=*" } { "" } } */
 /* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
-/* { dg-options "-march=armv7-a -mfloat-abi=hard -O2" } */
+/* { dg-options "-march=armv7-a+fp -mfloat-abi=hard -O2" } */
 
 void bar (int);
 
diff --git a/libgcc/config/arm/cmse_nonsecure_call.S b/libgcc/config/arm/cmse_nonsecure_call.S
index 653ad14..9b7dbb4 100644
--- a/libgcc/config/arm/cmse_nonsecure_call.S
+++ b/libgcc/config/arm/cmse_nonsecure_call.S
@@ -24,6 +24,14 @@
    <http://www.gnu.org/licenses/>.  */
 
 .syntax unified
+#ifdef __ARM_PCS_VFP
+# if __ARM_FP & 0x8
+	.fpu fpv5-d16
+# else
+	.fpu fpv4-sp-d16
+# endif
+#endif
+
 .thumb
 .global __gnu_cmse_nonsecure_call
 __gnu_cmse_nonsecure_call:

Christophe Lyon June 14, 2017, 9:08 a.m. UTC | #15
On 13 June 2017 at 19:35, Richard Earnshaw (lists)
<Richard.Earnshaw@arm.com> wrote:
> On 09/06/17 13:53, Richard Earnshaw wrote:

>>

>> During the ARM BoF at the Cauldron last year I mentioned that I wanted

>> to rework the way GCC on ARM handles the command line options.  The

>> problem was that most users, and even many experts, can't remember

>> which FPU/SIMD unit comes with which CPU and that consequently many

>> users were inadvertenly generating sub-optimal code for their system.

>>

>> This patch series implements the proposed change and provides support

>> for a generic way of adding optional features to architectures and CPU

>> names.  The documentation patches at the end of the series explain the

>> new syntax, so I won't repeat all that here.  Suffice to say here that

>> the result is that the -mfpu option now defaults to 'auto', which

>> allows the compiler to infer the floating-point and simd options from

>> the CPU/architecture options and that these options can normally be

>> expressed in a context-specific manner like +simd or +fp without

>> having to know precisely which variant is implemented.  Long term I'd

>> like to deprecate -mfpu and entirely move over to the new syntax; but

>> it's too early to start that process now.

>>

>> All the patches in the series should build a working basic compiler,

>> but the multilib selection will not work correctly until the relevant

>> patches towards the end are applied.  It is not really feasible to

>> retain that functionality without collapsing too many of the patches

>> together into one hunk.  It's also possible that some tests in the

>> testsuite may exhibit transient misbehaviour, but there should be no

>> regressions by the end of the sequence (some tests no-longer run in

>> the default configurations because the default CPU does not have

>> floating-point support).

>>

>> Just two patches are to the generic code, but both are fairly trivial.

>> One permits the sbitmap code to be used in the driver programs and the

>> other provides a way of escaping the meta-character in some multilib

>> reuse strings.

>>

>> I won't apply any of this series until those two patches have been

>> approved, and I won't commit anything before the middle of next week

>> even then.  This is a fairly complex change and it deserves some time

>> for people to comment before committing.

>>

>

> The attached is a roll-up of the entire series after the updates I've

> posted today.  This should eliminate any potential issues with applying

> the series for the purposes of testing.  Please don't post issues in

> reply to this, but to the individual patches in the series.

>


Hi Richard,

Thanks for the quick iteration, and sorry for responding here ;-)
The validation results of the whole roll-up patch look much better:
http://people.linaro.org/~christophe.lyon/cross-validation/gcc-test-patches/248942-roll-up.patch/report-build-info.html

(you can ignore the "better" in the arm-none-linux-gnueabihf table,
it's noise in the results).

The other 2 better are actually 100 "pass" becoming 26 "unsupported"
because arm_fp_ok now returns false in the corresponding configs
(there's no fpu for the selected processor/arch)

As of the regression --with-cpu=cortex-m3, the thumb2-slow-flash-data-[2345].c
tests may need an update: they are compiled with
-march=armv7e-m -mfloat-abi=hard -O2 -mthumb -mslow-flash-data
resulting in:
cc1: error: -mfloat-abi=hard: selected processor lacks an FPU

Christophe


> R.
Richard Earnshaw (lists) June 14, 2017, 10:21 a.m. UTC | #16
On 14/06/17 10:08, Christophe Lyon wrote:
> On 13 June 2017 at 19:35, Richard Earnshaw (lists)

> <Richard.Earnshaw@arm.com> wrote:

>> On 09/06/17 13:53, Richard Earnshaw wrote:

>>>

>>> During the ARM BoF at the Cauldron last year I mentioned that I wanted

>>> to rework the way GCC on ARM handles the command line options.  The

>>> problem was that most users, and even many experts, can't remember

>>> which FPU/SIMD unit comes with which CPU and that consequently many

>>> users were inadvertenly generating sub-optimal code for their system.

>>>

>>> This patch series implements the proposed change and provides support

>>> for a generic way of adding optional features to architectures and CPU

>>> names.  The documentation patches at the end of the series explain the

>>> new syntax, so I won't repeat all that here.  Suffice to say here that

>>> the result is that the -mfpu option now defaults to 'auto', which

>>> allows the compiler to infer the floating-point and simd options from

>>> the CPU/architecture options and that these options can normally be

>>> expressed in a context-specific manner like +simd or +fp without

>>> having to know precisely which variant is implemented.  Long term I'd

>>> like to deprecate -mfpu and entirely move over to the new syntax; but

>>> it's too early to start that process now.

>>>

>>> All the patches in the series should build a working basic compiler,

>>> but the multilib selection will not work correctly until the relevant

>>> patches towards the end are applied.  It is not really feasible to

>>> retain that functionality without collapsing too many of the patches

>>> together into one hunk.  It's also possible that some tests in the

>>> testsuite may exhibit transient misbehaviour, but there should be no

>>> regressions by the end of the sequence (some tests no-longer run in

>>> the default configurations because the default CPU does not have

>>> floating-point support).

>>>

>>> Just two patches are to the generic code, but both are fairly trivial.

>>> One permits the sbitmap code to be used in the driver programs and the

>>> other provides a way of escaping the meta-character in some multilib

>>> reuse strings.

>>>

>>> I won't apply any of this series until those two patches have been

>>> approved, and I won't commit anything before the middle of next week

>>> even then.  This is a fairly complex change and it deserves some time

>>> for people to comment before committing.

>>>

>>

>> The attached is a roll-up of the entire series after the updates I've

>> posted today.  This should eliminate any potential issues with applying

>> the series for the purposes of testing.  Please don't post issues in

>> reply to this, but to the individual patches in the series.

>>

> 

> Hi Richard,

> 

> Thanks for the quick iteration, and sorry for responding here ;-)

> The validation results of the whole roll-up patch look much better:

> http://people.linaro.org/~christophe.lyon/cross-validation/gcc-test-patches/248942-roll-up.patch/report-build-info.html

> 


No problem, that request is aimed at code reviews, not at overall
comments on the test results.

> (you can ignore the "better" in the arm-none-linux-gnueabihf table,

> it's noise in the results).

> 

> The other 2 better are actually 100 "pass" becoming 26 "unsupported"

> because arm_fp_ok now returns false in the corresponding configs

> (there's no fpu for the selected processor/arch)


That's somewhat expected, and in some ways the 'right thing'.  The
selected target really doesn't have an FPU so it's correct that the
infrastructure deduces this.

Of course, we might want to adjust the tests so that they do try harder
to enable an FPU, but that can be done later on a case by case basis.

> 

> As of the regression --with-cpu=cortex-m3, the thumb2-slow-flash-data-[2345].c

> tests may need an update: they are compiled with

> -march=armv7e-m -mfloat-abi=hard -O2 -mthumb -mslow-flash-data

> resulting in:

> cc1: error: -mfloat-abi=hard: selected processor lacks an FPU

> 


Yes, those need updating to -march=armv7e-m+fp.  The tests are somewhat
bogus in that they are assuming that the internal 'vfp' fpu that was
previously configured was 'right' for this architecture.  That
assumption was bogus and it's this sort of nonsense that this patch set
is really trying to address.

Many thanks for the quick turn-around on the tests again.  It looks like
we're nearly there.

I'll update patch 32 to add these changes, but won't bother with another
roll-up this time.

R.


> Christophe

> 

> 

>> R.
Richard Earnshaw (lists) June 14, 2017, 2:27 p.m. UTC | #17
On 13/06/17 18:29, Richard Earnshaw (lists) wrote:
> This test was overriding the options that had been detected as being

> necessary to enable Neon.  The result was that the combination of the

> test's options and those auto-detected were not compatible with neon

> leading to a test failure.  The correct fix here is to stick with the

> options that dg-add-options arm_neon has worked out.

> 

> 	* gcc.target/arm/neon-thumb2-move.c (dg-options): Don't override

> 	the architecture options added by dg-add-options arm_neon.

> 

> 


The thumb2-slow-flash-data tests were relying (incorrectly) on a
particular FPU being enabled by default.  These tests are fixed by
adding +fp to the architecture selected.

	* gcc.target/arm/neon-thumb2-move.c (dg-options): Don't override
	the architecture options added by dg-add-options arm_neon.
	* gcc.target/arm/thumb2-slow-flash-data-2.c (dg-opitions): Add +fp
	to the architecture.
	* gcc.target/arm/thumb3-slow-flash-data-3.c (dg-opitions): Likewise.
	* gcc.target/arm/thumb4-slow-flash-data-3.c (dg-opitions): Likewise.
	* gcc.target/arm/thumb5-slow-flash-data-3.c (dg-opitions): Likewise.


R.diff --git a/gcc/testsuite/gcc.target/arm/neon-thumb2-move.c b/gcc/testsuite/gcc.target/arm/neon-thumb2-move.c
index 9cf86dd..d8c6748 100644
--- a/gcc/testsuite/gcc.target/arm/neon-thumb2-move.c
+++ b/gcc/testsuite/gcc.target/arm/neon-thumb2-move.c
@@ -1,7 +1,7 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target arm_neon_ok } */
 /* { dg-require-effective-target arm_thumb2_ok } */
-/* { dg-options "-O2 -mthumb -march=armv7-a" } */
+/* { dg-options "-O2 -mthumb" } */
 /* { dg-add-options arm_neon } */
 /* { dg-prune-output "switch .* conflicts with" } */
 
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-2.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-2.c
index 6e76043..c87e050 100644
--- a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-2.c
+++ b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-2.c
@@ -3,7 +3,7 @@
 /* { dg-require-effective-target arm_thumb2_ok } */
 /* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */
 /* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
-/* { dg-options "-march=armv7e-m -mfloat-abi=hard -O2 -mthumb -mslow-flash-data" } */
+/* { dg-options "-march=armv7e-m+fp -mfloat-abi=hard -O2 -mthumb -mslow-flash-data" } */
 
 float f (float);
 
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-3.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-3.c
index fe7a12b..8c6210e 100644
--- a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-3.c
+++ b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-3.c
@@ -3,7 +3,7 @@
 /* { dg-require-effective-target arm_thumb2_ok } */
 /* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */
 /* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
-/* { dg-options "-march=armv7e-m -mfloat-abi=hard -mthumb -mslow-flash-data" } */
+/* { dg-options "-march=armv7e-m+fp -mfloat-abi=hard -mthumb -mslow-flash-data" } */
 
 /* From PR71607 */
 
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-4.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-4.c
index cc5aea4..1bcb692 100644
--- a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-4.c
+++ b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-4.c
@@ -3,7 +3,7 @@
 /* { dg-require-effective-target arm_thumb2_ok } */
 /* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */
 /* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
-/* { dg-options "-march=armv7e-m -mfloat-abi=hard -O2 -mthumb -mslow-flash-data" } */
+/* { dg-options "-march=armv7e-m+fp -mfloat-abi=hard -O2 -mthumb -mslow-flash-data" } */
 
 double __attribute__ ((target ("fpu=fpv5-d16")))
 foo (void)
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-5.c b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-5.c
index b9161c4..808fff0 100644
--- a/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-5.c
+++ b/gcc/testsuite/gcc.target/arm/thumb2-slow-flash-data-5.c
@@ -3,7 +3,7 @@
 /* { dg-require-effective-target arm_thumb2_ok } */
 /* { dg-skip-if "avoid conflicts with multilib options" { *-*-* } { "-mcpu=*" } { "-mcpu=cortex-m4" "-mcpu=cortex-m7" } } */
 /* { dg-skip-if "do not override -mfloat-abi" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" } } */
-/* { dg-options "-march=armv7e-m -mfloat-abi=hard -O2 -mthumb -mslow-flash-data" } */
+/* { dg-options "-march=armv7e-m+fp -mfloat-abi=hard -O2 -mthumb -mslow-flash-data" } */
 
 double __attribute__ ((target ("fpu=fpv5-sp-d16")))
 foo (void)

Christophe Lyon June 14, 2017, 7:26 p.m. UTC | #18
On 14 June 2017 at 16:27, Richard Earnshaw (lists)
<Richard.Earnshaw@arm.com> wrote:
> On 13/06/17 18:29, Richard Earnshaw (lists) wrote:

>> This test was overriding the options that had been detected as being

>> necessary to enable Neon.  The result was that the combination of the

>> test's options and those auto-detected were not compatible with neon

>> leading to a test failure.  The correct fix here is to stick with the

>> options that dg-add-options arm_neon has worked out.

>>

>>       * gcc.target/arm/neon-thumb2-move.c (dg-options): Don't override

>>       the architecture options added by dg-add-options arm_neon.

>>

>>

>

> The thumb2-slow-flash-data tests were relying (incorrectly) on a

> particular FPU being enabled by default.  These tests are fixed by

> adding +fp to the architecture selected.

>

>         * gcc.target/arm/neon-thumb2-move.c (dg-options): Don't override

>         the architecture options added by dg-add-options arm_neon.

>         * gcc.target/arm/thumb2-slow-flash-data-2.c (dg-opitions): Add +fp

>         to the architecture.

>         * gcc.target/arm/thumb3-slow-flash-data-3.c (dg-opitions): Likewise.

>         * gcc.target/arm/thumb4-slow-flash-data-3.c (dg-opitions): Likewise.

>         * gcc.target/arm/thumb5-slow-flash-data-3.c (dg-opitions): Likewise.

>


I confirm they now pass on my side:
http://people.linaro.org/~christophe.lyon/cross-validation/gcc-test-patches/248942-roll-up.patch2/report-build-info.html

>

> R.
Richard Earnshaw June 16, 2017, 9:11 p.m. UTC | #19
On 13/06/17 18:35, Richard Earnshaw (lists) wrote:
> On 09/06/17 13:53, Richard Earnshaw wrote:

>>

>> During the ARM BoF at the Cauldron last year I mentioned that I wanted

>> to rework the way GCC on ARM handles the command line options.  The

>> problem was that most users, and even many experts, can't remember

>> which FPU/SIMD unit comes with which CPU and that consequently many

>> users were inadvertenly generating sub-optimal code for their system.

>>

>> This patch series implements the proposed change and provides support

>> for a generic way of adding optional features to architectures and CPU

>> names.  The documentation patches at the end of the series explain the

>> new syntax, so I won't repeat all that here.  Suffice to say here that

>> the result is that the -mfpu option now defaults to 'auto', which

>> allows the compiler to infer the floating-point and simd options from

>> the CPU/architecture options and that these options can normally be

>> expressed in a context-specific manner like +simd or +fp without

>> having to know precisely which variant is implemented.  Long term I'd

>> like to deprecate -mfpu and entirely move over to the new syntax; but

>> it's too early to start that process now.

>>

>> All the patches in the series should build a working basic compiler,

>> but the multilib selection will not work correctly until the relevant

>> patches towards the end are applied.  It is not really feasible to

>> retain that functionality without collapsing too many of the patches

>> together into one hunk.  It's also possible that some tests in the

>> testsuite may exhibit transient misbehaviour, but there should be no

>> regressions by the end of the sequence (some tests no-longer run in

>> the default configurations because the default CPU does not have

>> floating-point support).

>>

>> Just two patches are to the generic code, but both are fairly trivial.

>> One permits the sbitmap code to be used in the driver programs and the

>> other provides a way of escaping the meta-character in some multilib

>> reuse strings.

>>

>> I won't apply any of this series until those two patches have been

>> approved, and I won't commit anything before the middle of next week

>> even then.  This is a fairly complex change and it deserves some time

>> for people to comment before committing.

>>

> 

> The attached is a roll-up of the entire series after the updates I've

> posted today.  This should eliminate any potential issues with applying

> the series for the purposes of testing.  Please don't post issues in

> reply to this, but to the individual patches in the series.

> 

> R.

> 


This series has now been committed after rebasing on to the latest
trunk.  Nothing material has changed so I'm not reposting the patches again.

"Let the mayhem begin..."

R.
Ramana Radhakrishnan June 16, 2017, 9:16 p.m. UTC | #20
On Fri, Jun 16, 2017 at 10:11 PM, Richard Earnshaw
<Richard.Earnshaw@foss.arm.com> wrote:
> On 13/06/17 18:35, Richard Earnshaw (lists) wrote:

>> On 09/06/17 13:53, Richard Earnshaw wrote:

>>>

>>> During the ARM BoF at the Cauldron last year I mentioned that I wanted

>>> to rework the way GCC on ARM handles the command line options.  The

>>> problem was that most users, and even many experts, can't remember

>>> which FPU/SIMD unit comes with which CPU and that consequently many

>>> users were inadvertenly generating sub-optimal code for their system.

>>>

>>> This patch series implements the proposed change and provides support

>>> for a generic way of adding optional features to architectures and CPU

>>> names.  The documentation patches at the end of the series explain the

>>> new syntax, so I won't repeat all that here.  Suffice to say here that

>>> the result is that the -mfpu option now defaults to 'auto', which

>>> allows the compiler to infer the floating-point and simd options from

>>> the CPU/architecture options and that these options can normally be

>>> expressed in a context-specific manner like +simd or +fp without

>>> having to know precisely which variant is implemented.  Long term I'd

>>> like to deprecate -mfpu and entirely move over to the new syntax; but

>>> it's too early to start that process now.

>>>

>>> All the patches in the series should build a working basic compiler,

>>> but the multilib selection will not work correctly until the relevant

>>> patches towards the end are applied.  It is not really feasible to

>>> retain that functionality without collapsing too many of the patches

>>> together into one hunk.  It's also possible that some tests in the

>>> testsuite may exhibit transient misbehaviour, but there should be no

>>> regressions by the end of the sequence (some tests no-longer run in

>>> the default configurations because the default CPU does not have

>>> floating-point support).

>>>

>>> Just two patches are to the generic code, but both are fairly trivial.

>>> One permits the sbitmap code to be used in the driver programs and the

>>> other provides a way of escaping the meta-character in some multilib

>>> reuse strings.

>>>

>>> I won't apply any of this series until those two patches have been

>>> approved, and I won't commit anything before the middle of next week

>>> even then.  This is a fairly complex change and it deserves some time

>>> for people to comment before committing.

>>>

>>

>> The attached is a roll-up of the entire series after the updates I've

>> posted today.  This should eliminate any potential issues with applying

>> the series for the purposes of testing.  Please don't post issues in

>> reply to this, but to the individual patches in the series.

>>

>> R.

>>

>

> This series has now been committed after rebasing on to the latest

> trunk.  Nothing material has changed so I'm not reposting the patches again.

>


Yay !

This is definitely a user visible change and it would be great to put
this into the release notes for GCC 8.

Ramana

> "Let the mayhem begin..."

>

> R.