From 34ef62f46541d423b991850b2b7ba34d8749a6ba Mon Sep 17 00:00:00 2001 From: Andre Vieira Date: Mon, 1 Apr 2019 10:43:32 +0100 Subject: [PATCH] [GAS, Arm] CLI with architecture sensitive extensions This patch adds a new framework to add architecture sensitive extensions, like GCC does. This patch also implements all architecture extensions currently available in GCC. This framework works as follows. To enable architecture sensitive extensions for a particular architecture, that architecture must contain an ARM_ARCH_OPT2 entry in the 'arm_archs' table. All fields here are the same as previous, with the addition of a new extra field at the end to it's extension table. This , corresponds to a _ext_table of type 'struct arm_ext_table'. This struct can be filled with three types of entries: ARM_ADD (string , arm_feature_set ), which means + will enable ARM_REMOVE (string , arm_feature_set ), which means +no will disable ARM_EXT (string , arm_feature_set , arm_feature_set ), which means + will enable and +no will disable (this is to be used instead of adding an ARM_ADD and ARM_REMOVE for the same ) This patch does not disable the use of the old extensions, even if some of them are duplicated in the new tables. This is a "in-between-step" as we may want to deprecate the old table of extensions in later patches. For now, GAS will first look for the + or +no in the new table and if no entry is found it will continue searching in the old table, following old behaviour. If only an ARM_ADD or an ARM_REMOVE is defined for and +no or + resp. is used then it also continues to search the old table for it. A couple of caveats: - This patch does not enable the use of these architecture extensions with the '.arch_extension' directive. This is future work that I will tend to later. - This patch does not enable the use of these architecture extensions with the -mcpu option. This is future work that I will tend to later. - This patch does not change the current behaviour when combining an architecture extension and using -mfpu on the command-line. The current behaviour of GAS is to stage the union of feature bits enabled by both -march and -mfpu. GCC behaves differently here, so this is something we may want to revisit on a later date. --- gas/ChangeLog | 61 ++++ gas/config/tc-arm.c | 316 +++++++++++++++--- gas/doc/c-arm.texi | 167 ++++++++- .../gas/arm/armv8-2-fp16-scalar-bad-ext.d | 4 + .../gas/arm/armv8-2-fp16-scalar-ext.d | 75 +++++ .../gas/arm/armv8-2-fp16-scalar-thumb-ext.d | 75 +++++ gas/testsuite/gas/arm/armv8-2-fp16-simd-ext.d | 159 +++++++++ .../gas/arm/armv8-2-fp16-simd-thumb-ext.d | 159 +++++++++ .../gas/arm/armv8-2-fp16-simd-warning-ext.d | 4 + .../arm/armv8-2-fp16-simd-warning-thumb-ext.d | 4 + gas/testsuite/gas/arm/armv8_2+rdma-ext.d | 79 +++++ .../gas/arm/armv8_2-a-fp16-thumb2-ext.d | 249 ++++++++++++++ gas/testsuite/gas/arm/armv8_2-a-fp16_ext.d | 249 ++++++++++++++ gas/testsuite/gas/arm/armv8_3-a-fp-bad-ext.d | 3 + gas/testsuite/gas/arm/armv8_3-a-fp-ext.d | 16 + gas/testsuite/gas/arm/armv8_3-a-fp16-ext.d | 249 ++++++++++++++ .../gas/arm/armv8_3-a-simd-bad-ext.d | 3 + gas/testsuite/gas/arm/armv8_4-a-fp16-ext.d | 249 ++++++++++++++ gas/testsuite/gas/arm/armv8m.main+fp.d | 32 ++ gas/testsuite/gas/arm/armv8m.main+fp.dp.d | 63 ++++ gas/testsuite/gas/arm/attr-ext-fpv5-d16.d | 14 + gas/testsuite/gas/arm/attr-ext-fpv5.d | 15 + gas/testsuite/gas/arm/attr-ext-idiv.d | 15 + gas/testsuite/gas/arm/attr-ext-mp.d | 15 + gas/testsuite/gas/arm/attr-ext-neon-fp16.d | 20 ++ gas/testsuite/gas/arm/attr-ext-neon-vfpv3.d | 16 + gas/testsuite/gas/arm/attr-ext-neon-vfpv4.d | 19 ++ gas/testsuite/gas/arm/attr-ext-sec.d | 15 + .../gas/arm/attr-ext-vfpv3-d16-fp16.d | 21 ++ gas/testsuite/gas/arm/attr-ext-vfpv3-d16.d | 14 + gas/testsuite/gas/arm/attr-ext-vfpv3-fp16.d | 20 ++ gas/testsuite/gas/arm/attr-ext-vfpv3.d | 15 + gas/testsuite/gas/arm/attr-ext-vfpv3xd-fp.d | 17 + gas/testsuite/gas/arm/attr-ext-vfpv3xd.d | 16 + gas/testsuite/gas/arm/attr-ext-vfpv4-d16.d | 18 + gas/testsuite/gas/arm/attr-ext-vfpv4-sp-d16.d | 15 + gas/testsuite/gas/arm/attr-ext-vfpv4.d | 18 + gas/testsuite/gas/arm/attr-mfpu-neon-fp16.d | 8 +- gas/testsuite/gas/arm/dotprod-mandatory-ext.d | 297 ++++++++++++++++ gas/testsuite/gas/arm/fpv5-d16.s | 58 ++++ gas/testsuite/gas/arm/fpv5-sp-d16.s | 27 ++ include/ChangeLog | 11 + include/opcode/arm.h | 31 +- 43 files changed, 2878 insertions(+), 53 deletions(-) create mode 100644 gas/testsuite/gas/arm/armv8-2-fp16-scalar-bad-ext.d create mode 100644 gas/testsuite/gas/arm/armv8-2-fp16-scalar-ext.d create mode 100644 gas/testsuite/gas/arm/armv8-2-fp16-scalar-thumb-ext.d create mode 100644 gas/testsuite/gas/arm/armv8-2-fp16-simd-ext.d create mode 100644 gas/testsuite/gas/arm/armv8-2-fp16-simd-thumb-ext.d create mode 100644 gas/testsuite/gas/arm/armv8-2-fp16-simd-warning-ext.d create mode 100644 gas/testsuite/gas/arm/armv8-2-fp16-simd-warning-thumb-ext.d create mode 100644 gas/testsuite/gas/arm/armv8_2+rdma-ext.d create mode 100644 gas/testsuite/gas/arm/armv8_2-a-fp16-thumb2-ext.d create mode 100644 gas/testsuite/gas/arm/armv8_2-a-fp16_ext.d create mode 100644 gas/testsuite/gas/arm/armv8_3-a-fp-bad-ext.d create mode 100644 gas/testsuite/gas/arm/armv8_3-a-fp-ext.d create mode 100644 gas/testsuite/gas/arm/armv8_3-a-fp16-ext.d create mode 100644 gas/testsuite/gas/arm/armv8_3-a-simd-bad-ext.d create mode 100644 gas/testsuite/gas/arm/armv8_4-a-fp16-ext.d create mode 100644 gas/testsuite/gas/arm/armv8m.main+fp.d create mode 100644 gas/testsuite/gas/arm/armv8m.main+fp.dp.d create mode 100644 gas/testsuite/gas/arm/attr-ext-fpv5-d16.d create mode 100644 gas/testsuite/gas/arm/attr-ext-fpv5.d create mode 100644 gas/testsuite/gas/arm/attr-ext-idiv.d create mode 100644 gas/testsuite/gas/arm/attr-ext-mp.d create mode 100644 gas/testsuite/gas/arm/attr-ext-neon-fp16.d create mode 100644 gas/testsuite/gas/arm/attr-ext-neon-vfpv3.d create mode 100644 gas/testsuite/gas/arm/attr-ext-neon-vfpv4.d create mode 100644 gas/testsuite/gas/arm/attr-ext-sec.d create mode 100644 gas/testsuite/gas/arm/attr-ext-vfpv3-d16-fp16.d create mode 100644 gas/testsuite/gas/arm/attr-ext-vfpv3-d16.d create mode 100644 gas/testsuite/gas/arm/attr-ext-vfpv3-fp16.d create mode 100644 gas/testsuite/gas/arm/attr-ext-vfpv3.d create mode 100644 gas/testsuite/gas/arm/attr-ext-vfpv3xd-fp.d create mode 100644 gas/testsuite/gas/arm/attr-ext-vfpv3xd.d create mode 100644 gas/testsuite/gas/arm/attr-ext-vfpv4-d16.d create mode 100644 gas/testsuite/gas/arm/attr-ext-vfpv4-sp-d16.d create mode 100644 gas/testsuite/gas/arm/attr-ext-vfpv4.d create mode 100644 gas/testsuite/gas/arm/dotprod-mandatory-ext.d create mode 100644 gas/testsuite/gas/arm/fpv5-d16.s create mode 100644 gas/testsuite/gas/arm/fpv5-sp-d16.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 69c19521605..0e7a07c328c 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,64 @@ +2019-04-01 Andre Vieira + + * config/tc-arm.c (arm_ext_table): New struct type. + (arm_arch_option_table): Add new 'arm_ext_table' field. + (ARM_EXT,ARM_ADD,ARM_REMOVE, ALL_FP): New macros. + (armv5te_ext_table, armv7ve_ext_table, armv7a_ext_table, + armv7r_ext_table, armv7em_ext_table, armv8a_ext_table, + armv81a_ext_table, armv82a_ext_table, armv84a_ext_table, + armv85a_ext_table, armv8m_main_ext_table, + armv8r_ext_table): New architecture extension tables. + (ARM_ARCH_OPT): Add new default field. + (ARM_ARCH_OPT2): New macro. + (arm_archs): Extend some architectures with the new architecture + extension tables mentioned above. + (arm_extensions): Add DEPRECATED comment with instructions to + use new table. + (arm_parse_extension): Change to use new extension tables. + (arm_parse_cpu): Don't change existing behavior. + (arm_parse_arch): Change to use new extension tables. + * doc/c-arm.texi: Document new architecture extensions. + * testsuite/gas/arm/attr-mfpu-neon-fp16.d: Change test to use new + extension option rather than -mfpu and change expected behaviour to + sane outputs. + * testsuite/gas/arm/armv8-2-fp16-scalar-bad-ext.d: New. + * testsuite/gas/arm/armv8-2-fp16-scalar-ext.d: New. + * testsuite/gas/arm/armv8-2-fp16-scalar-thumb-ext.d: New. + * testsuite/gas/arm/armv8-2-fp16-simd-ext.d: New. + * testsuite/gas/arm/armv8-2-fp16-simd-thumb-ext.d: New. + * testsuite/gas/arm/armv8-2-fp16-simd-warning-ext.d: New. + * testsuite/gas/arm/armv8-2-fp16-simd-warning-thumb-ext.d: New. + * testsuite/gas/arm/armv8_2+rdma-ext.d: New. + * testsuite/gas/arm/armv8_2-a-fp16-thumb2-ext.d: New. + * testsuite/gas/arm/armv8_2-a-fp16_ext.d: New. + * testsuite/gas/arm/armv8_3-a-fp-bad-ext.d: New. + * testsuite/gas/arm/armv8_3-a-fp-ext.d: New. + * testsuite/gas/arm/armv8_3-a-fp16-ext.d: New. + * testsuite/gas/arm/armv8_3-a-simd-bad-ext.d: New. + * testsuite/gas/arm/armv8_4-a-fp16-ext.d: New. + * testsuite/gas/arm/armv8m.main+fp.d: New. + * testsuite/gas/arm/armv8m.main+fp.dp.d: New. + * testsuite/gas/arm/attr-ext-fpv5-d16.d: New. + * testsuite/gas/arm/attr-ext-fpv5.d: New. + * testsuite/gas/arm/attr-ext-idiv.d: New. + * testsuite/gas/arm/attr-ext-mp.d: New. + * testsuite/gas/arm/attr-ext-neon-fp16.d: New. + * testsuite/gas/arm/attr-ext-neon-vfpv3.d: New. + * testsuite/gas/arm/attr-ext-neon-vfpv4.d: New. + * testsuite/gas/arm/attr-ext-sec.d: New. + * testsuite/gas/arm/attr-ext-vfpv3-d16-fp16.d: New. + * testsuite/gas/arm/attr-ext-vfpv3-d16.d: New. + * testsuite/gas/arm/attr-ext-vfpv3-fp16.d: New. + * testsuite/gas/arm/attr-ext-vfpv3.d: New. + * testsuite/gas/arm/attr-ext-vfpv3xd-fp.d: New. + * testsuite/gas/arm/attr-ext-vfpv3xd.d: New. + * testsuite/gas/arm/attr-ext-vfpv4-d16.d: New. + * testsuite/gas/arm/attr-ext-vfpv4-sp-d16.d: New. + * testsuite/gas/arm/attr-ext-vfpv4.d: New. + * testsuite/gas/arm/dotprod-mandatory-ext.d: New. + * testsuite/gas/arm/fpv5-d16.s: New. + * testsuite/gas/arm/fpv5-sp-d16.s: New. + 2019-03-28 Alan Modra PR 24390 diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 5bcd88ba8fe..4218d059d6d 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -26308,17 +26308,217 @@ static const struct arm_cpu_option_table arm_cpus[] = }; #undef ARM_CPU_OPT +struct arm_ext_table +{ + const char * name; + size_t name_len; + const arm_feature_set merge; + const arm_feature_set clear; +}; + struct arm_arch_option_table { - const char * name; - size_t name_len; - const arm_feature_set value; - const arm_feature_set default_fpu; + const char * name; + size_t name_len; + const arm_feature_set value; + const arm_feature_set default_fpu; + const struct arm_ext_table * ext_table; +}; + +/* Used to add support for +E and +noE extension. */ +#define ARM_EXT(E, M, C) { E, sizeof (E) - 1, M, C } +/* Used to add support for a +E extension. */ +#define ARM_ADD(E, M) { E, sizeof(E) - 1, M, ARM_ARCH_NONE } +/* Used to add support for a +noE extension. */ +#define ARM_REMOVE(E, C) { E, sizeof(E) -1, ARM_ARCH_NONE, C } + +#define ALL_FP ARM_FEATURE (0, ARM_EXT2_FP16_INST | ARM_EXT2_FP16_FML, \ + ~0 & ~FPU_ENDIAN_PURE) + +static const struct arm_ext_table armv5te_ext_table[] = +{ + ARM_EXT ("fp", FPU_ARCH_VFP_V2, ALL_FP), + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } +}; + +static const struct arm_ext_table armv7_ext_table[] = +{ + ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP), + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } +}; + +static const struct arm_ext_table armv7ve_ext_table[] = +{ + ARM_EXT ("fp", FPU_ARCH_VFP_V4D16, ALL_FP), + ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), + ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3), + ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16), + ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16), + ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16), /* Alias for +fp. */ + ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4), + + ARM_EXT ("simd", FPU_ARCH_NEON_VFP_V4, + ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)), + + /* Aliases for +simd. */ + ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4), + + ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1), + ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1), + ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16), + + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } +}; + +static const struct arm_ext_table armv7a_ext_table[] = +{ + ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP), + ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */ + ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3), + ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16), + ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16), + ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16), + ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4), + + ARM_EXT ("simd", FPU_ARCH_VFP_V3_PLUS_NEON_V1, + ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)), + + /* Aliases for +simd. */ + ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1), + ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1), + + ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16), + ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4), + + ARM_ADD ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP)), + ARM_ADD ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC)), + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } +}; + +static const struct arm_ext_table armv7r_ext_table[] = +{ + ARM_ADD ("fp.sp", FPU_ARCH_VFP_V3xD), + ARM_ADD ("vfpv3xd", FPU_ARCH_VFP_V3xD), /* Alias for +fp.sp. */ + ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP), + ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */ + ARM_ADD ("vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16), + ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16), + ARM_EXT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV), + ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV)), + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } +}; + +static const struct arm_ext_table armv7em_ext_table[] = +{ + ARM_EXT ("fp", FPU_ARCH_VFP_V4_SP_D16, ALL_FP), + /* Alias for +fp, used to be known as fpv4-sp-d16. */ + ARM_ADD ("vfpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16), + ARM_ADD ("fpv5", FPU_ARCH_VFP_V5_SP_D16), + ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16), + ARM_ADD ("fpv5-d16", FPU_ARCH_VFP_V5D16), + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } +}; + +static const struct arm_ext_table armv8a_ext_table[] = +{ + ARM_ADD ("crc", ARCH_CRC_ARMV8), + ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8), + ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8, + ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)), + + /* Armv8-a does not allow an FP implementation without SIMD, so the user + should use the +simd option to turn on FP. */ + ARM_REMOVE ("fp", ALL_FP), + ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)), + ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)), + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } +}; + + +static const struct arm_ext_table armv81a_ext_table[] = +{ + ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1), + ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1, + ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)), + + /* Armv8-a does not allow an FP implementation without SIMD, so the user + should use the +simd option to turn on FP. */ + ARM_REMOVE ("fp", ALL_FP), + ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)), + ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)), + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } +}; + +static const struct arm_ext_table armv82a_ext_table[] = +{ + ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1), + ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_2_FP16), + ARM_ADD ("fp16fml", FPU_ARCH_NEON_VFP_ARMV8_2_FP16FML), + ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1, + ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)), + ARM_ADD ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8), + + /* Armv8-a does not allow an FP implementation without SIMD, so the user + should use the +simd option to turn on FP. */ + ARM_REMOVE ("fp", ALL_FP), + ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)), + ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)), + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } +}; + +static const struct arm_ext_table armv84a_ext_table[] = +{ + ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8), + ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML), + ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4, + ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)), + + /* Armv8-a does not allow an FP implementation without SIMD, so the user + should use the +simd option to turn on FP. */ + ARM_REMOVE ("fp", ALL_FP), + ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)), + ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)), + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } +}; + +static const struct arm_ext_table armv85a_ext_table[] = +{ + ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8), + ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML), + ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4, + ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)), + + /* Armv8-a does not allow an FP implementation without SIMD, so the user + should use the +simd option to turn on FP. */ + ARM_REMOVE ("fp", ALL_FP), + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } +}; + +static const struct arm_ext_table armv8m_main_ext_table[] = +{ + ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP), + ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)), + ARM_EXT ("fp", FPU_ARCH_VFP_V5_SP_D16, ALL_FP), + ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16), + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } +}; + +static const struct arm_ext_table armv8r_ext_table[] = +{ + ARM_ADD ("crc", ARCH_CRC_ARMV8), + ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8), + ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8, + ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)), + ARM_REMOVE ("fp", ALL_FP), + ARM_ADD ("fp.sp", FPU_ARCH_VFP_V5_SP_D16), + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } }; /* This list should, at a minimum, contain all the architecture names recognized by GCC. */ -#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF } +#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF, NULL } +#define ARM_ARCH_OPT2(N, V, DF, ext) \ + { N, sizeof (N) - 1, V, DF, ext##_ext_table } static const struct arm_arch_option_table arm_archs[] = { @@ -26336,50 +26536,51 @@ static const struct arm_arch_option_table arm_archs[] = ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP), ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP), ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP), + ARM_ARCH_OPT2 ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP, armv5te), + ARM_ARCH_OPT2 ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP, armv5te), + ARM_ARCH_OPT2 ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP, armv5te), + ARM_ARCH_OPT2 ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te), + ARM_ARCH_OPT2 ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te), + ARM_ARCH_OPT2 ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP, armv5te), + ARM_ARCH_OPT2 ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP, armv5te), /* The official spelling of this variant is ARMv6KZ, the name "armv6zk" is kept to preserve existing behaviour. */ - ARM_ARCH_OPT ("armv6kz", ARM_ARCH_V6KZ, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv6zk", ARM_ARCH_V6KZ, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP), + ARM_ARCH_OPT2 ("armv6kz", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te), + ARM_ARCH_OPT2 ("armv6zk", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te), + ARM_ARCH_OPT2 ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP, armv5te), + ARM_ARCH_OPT2 ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP, armv5te), + ARM_ARCH_OPT2 ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP, armv5te), /* The official spelling of this variant is ARMv6KZ, the name "armv6zkt2" is kept to preserve existing behaviour. */ - ARM_ARCH_OPT ("armv6kzt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv6zkt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP), + ARM_ARCH_OPT2 ("armv6kzt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te), + ARM_ARCH_OPT2 ("armv6zkt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te), ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP), ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP), + ARM_ARCH_OPT2 ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP, armv7), /* The official spelling of the ARMv7 profile variants is the dashed form. Accept the non-dashed form for compatibility with old toolchains. */ - ARM_ARCH_OPT ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv7ve", ARM_ARCH_V7VE, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP), + ARM_ARCH_OPT2 ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a), + ARM_ARCH_OPT2 ("armv7ve", ARM_ARCH_V7VE, FPU_ARCH_VFP, armv7ve), + ARM_ARCH_OPT2 ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r), ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP), + ARM_ARCH_OPT2 ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a), + ARM_ARCH_OPT2 ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r), ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP), + ARM_ARCH_OPT2 ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP, armv7em), ARM_ARCH_OPT ("armv8-m.base", ARM_ARCH_V8M_BASE, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv8.2-a", ARM_ARCH_V8_2A, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv8.3-a", ARM_ARCH_V8_3A, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv8-r", ARM_ARCH_V8R, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv8.4-a", ARM_ARCH_V8_4A, FPU_ARCH_VFP), - ARM_ARCH_OPT ("armv8.5-a", ARM_ARCH_V8_5A, FPU_ARCH_VFP), + ARM_ARCH_OPT2 ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP, + armv8m_main), + ARM_ARCH_OPT2 ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP, armv8a), + ARM_ARCH_OPT2 ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP, armv81a), + ARM_ARCH_OPT2 ("armv8.2-a", ARM_ARCH_V8_2A, FPU_ARCH_VFP, armv82a), + ARM_ARCH_OPT2 ("armv8.3-a", ARM_ARCH_V8_3A, FPU_ARCH_VFP, armv82a), + ARM_ARCH_OPT2 ("armv8-r", ARM_ARCH_V8R, FPU_ARCH_VFP, armv8r), + ARM_ARCH_OPT2 ("armv8.4-a", ARM_ARCH_V8_4A, FPU_ARCH_VFP, armv84a), + ARM_ARCH_OPT2 ("armv8.5-a", ARM_ARCH_V8_5A, FPU_ARCH_VFP, armv85a), ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP), ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP), ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2, FPU_ARCH_VFP), - { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE } + { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL } }; #undef ARM_ARCH_OPT @@ -26402,6 +26603,8 @@ struct arm_option_extension_value_table #define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } } #define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} } +/* DEPRECATED: Refrain from using this table to add any new extensions, instead + use the context sensitive approach using arm_ext_table's. */ static const struct arm_option_extension_value_table arm_extensions[] = { ARM_EXT_OPT ("crc", ARCH_CRC_ARMV8, ARM_FEATURE_COPROC (CRC_EXT_ARMV8), @@ -26574,7 +26777,8 @@ struct arm_long_option_table static bfd_boolean arm_parse_extension (const char *str, const arm_feature_set *opt_set, - arm_feature_set *ext_set) + arm_feature_set *ext_set, + const struct arm_ext_table *ext_table) { /* We insist on extensions being specified in alphabetical order, and with extensions being added before being removed. We achieve this by having @@ -26640,6 +26844,41 @@ arm_parse_extension (const char *str, const arm_feature_set *opt_set, gas_assert (adding_value != -1); gas_assert (opt != NULL); + if (ext_table != NULL) + { + const struct arm_ext_table * ext_opt = ext_table; + bfd_boolean found = FALSE; + for (; ext_opt->name != NULL; ext_opt++) + if (ext_opt->name_len == len + && strncmp (ext_opt->name, str, len) == 0) + { + if (adding_value) + { + if (ARM_FEATURE_ZERO (ext_opt->merge)) + /* TODO: Option not supported. When we remove the + legacy table this case should error out. */ + continue; + + ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, ext_opt->merge); + } + else + { + if (ARM_FEATURE_ZERO (ext_opt->clear)) + /* TODO: Option not supported. When we remove the + legacy table this case should error out. */ + continue; + ARM_CLEAR_FEATURE (*ext_set, *ext_set, ext_opt->clear); + } + found = TRUE; + break; + } + if (found) + { + str = ext; + continue; + } + } + /* Scan over the options table trying to find an exact match. */ for (; opt->name != NULL; opt++) if (opt->name_len == len && strncmp (opt->name, str, len) == 0) @@ -26748,7 +26987,7 @@ arm_parse_cpu (const char *str) } if (ext != NULL) - return arm_parse_extension (ext, mcpu_cpu_opt, mcpu_ext_opt); + return arm_parse_extension (ext, mcpu_cpu_opt, mcpu_ext_opt, NULL); return TRUE; } @@ -26786,7 +27025,8 @@ arm_parse_arch (const char *str) strcpy (selected_cpu_name, opt->name); if (ext != NULL) - return arm_parse_extension (ext, march_cpu_opt, march_ext_opt); + return arm_parse_extension (ext, march_cpu_opt, march_ext_opt, + opt->ext_table); return TRUE; } diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi index 4fb6cadf935..184d7160a88 100644 --- a/gas/doc/c-arm.texi +++ b/gas/doc/c-arm.texi @@ -248,7 +248,9 @@ names are recognized: @code{armv8-r}, @code{armv8.4-a}, @code{armv8.5-a}, -@code{iwmmxt} +@code{armv8-m.base}, +@code{armv8-m.main}, +@code{iwmmxt}, @code{iwmmxt2} and @code{xscale}. @@ -256,8 +258,167 @@ If both @code{-mcpu} and @code{-march} are specified, the assembler will use the setting for @code{-mcpu}. -The architecture option can be extended with the same instruction set -extension options as the @code{-mcpu} option. +The architecture option can be extended with a set extension options. These +extensions are context sensitive, i.e. the same extension may mean different +things when used with different architectures. When used together with a +@code{-mfpu} option, the union of both feature enablement is taken. +See their availability and meaning below: + +For @code{armv5te}, @code{armv5texp}, @code{armv5tej}, @code{armv6}, @code{armv6j}, @code{armv6k}, @code{armv6z}, @code{armv6kz}, @code{armv6zk}, @code{armv6t2}, @code{armv6kt2} and @code{armv6zt2}: + +@code{+fp}: Enables VFPv2 instructions. +@code{+nofp}: Disables all FPU instrunctions. + +For @code{armv7}: + +@code{+fp}: Enables VFPv3 instructions with 16 double-word registers. +@code{+nofp}: Disables all FPU instructions. + +For @code{armv7-a}: + +@code{+fp}: Enables VFPv3 instructions with 16 double-word registers. +@code{+vfpv3-d16}: Alias for @code{+fp}. +@code{+vfpv3}: Enables VFPv3 instructions with 32 double-word registers. +@code{+vfpv3-d16-fp16}: Enables VFPv3 with half precision floating-point +conversion instructions and 16 double-word registers. +@code{+vfpv3-fp16}: Enables VFPv3 with half precision floating-point conversion +instructions and 32 double-word registers. +@code{+vfpv4-d16}: Enables VFPv4 instructions with 16 double-word registers. +@code{+vfpv4}: Enables VFPv4 instructions with 32 double-word registers. +@code{+simd}: Enables VFPv3 and NEONv1 instructions with 32 double-word +registers. +@code{+neon}: Alias for @code{+simd}. +@code{+neon-vfpv3}: Alias for @code{+simd}. +@code{+neon-fp16}: Enables VFPv3, half precision floating-point conversion and +NEONv1 instructions with 32 double-word registers. +@code{+neon-vfpv4}: Enables VFPv4 and NEONv1 with Fused-MAC instructions and 32 +double-word registers. +@code{+mp}: Enables Multiprocessing Extensions. +@code{+sec}: Enables Security Extensions. +@code{+nofp}: Disables all FPU and NEON instructions. +@code{+nosimd}: Disables all NEON instructions. + +For @code{armv7ve}: + +@code{+fp}: Enables VFPv4 instructions with 16 double-word registers. +@code{+vfpv4-d16}: Alias for @code{+fp}. +@code{+vfpv3-d16}: Enables VFPv3 instructions with 16 double-word registers. +@code{+vfpv3}: Enables VFPv3 instructions with 32 double-word registers. +@code{+vfpv3-d16-fp16}: Enables VFPv3 with half precision floating-point +conversion instructions and 16 double-word registers. +@code{+vfpv3-fp16}: Enables VFPv3 with half precision floating-point conversion +instructions and 32 double-word registers. +@code{+vfpv4}: Enables VFPv4 instructions with 32 double-word registers. +@code{+simd}: Enables VFPv4 and NEONv1 with Fused-MAC instructions and 32 +double-word registers. +@code{+neon-vfpv4}: Alias for @code{+simd}. +@code{+neon}: Enables VFPv3 and NEONv1 instructions with 32 double-word +registers. +@code{+neon-vfpv3}: Alias for @code{+neon}. +@code{+neon-fp16}: Enables VFPv3, half precision floating-point conversion and +NEONv1 instructions with 32 double-word registers. +double-word registers. +@code{+nofp}: Disables all FPU and NEON instructions. +@code{+nosimd}: Disables all NEON instructions. + +For @code{armv7-r}: + +@code{+fp.sp}: Enables single-precision only VFPv3 instructions with 16 +double-word registers. +@code{+vfpv3xd}: Alias for @code{+fp.sp}. +@code{+fp}: Enables VFPv3 instructions with 16 double-word registers. +@code{+vfpv3-d16}: Alias for @code{+fp}. +@code{+vfpv3xd-fp16}: Enables single-precision only VFPv3 and half +floating-point conversion instructions with 16 double-word registers. +@code{+vfpv3-d16-fp16}: Enables VFPv3 and half precision floating-point +conversion instructions with 16 double-word registers. +@code{+idiv}: Enables integer division instructions in ARM mode. +@code{+nofp}: Disables all FPU instructions. + +For @code{armv7e-m}: + +@code{+fp}: Enables single-precision only VFPv4 instructions with 16 +double-word registers. +@code{+vfpvf4-sp-d16}: Alias for @code{+fp}. +@code{+fpv5}: Enables single-precision only VFPv5 instructions with 16 +double-word registers. +@code{+fp.dp}: Enables VFPv5 instructions with 16 double-word registers. +@code{+fpv5-d16"}: Alias for @code{+fp.dp}. +@code{+nofp}: Disables all FPU instructions. + +For @code{armv8-m.main}: + +@code{+dsp}: Enables DSP Extension. +@code{+fp}: Enables single-precision only VFPv5 instructions with 16 +double-word registers. +@code{+fp.dp}: Enables VFPv5 instructions with 16 double-word registers. +@code{+nofp}: Disables all FPU instructions. +@code{+nodsp}: Disables DSP Extension. + +For @code{armv8-a}: + +@code{+crc}: Enables CRC32 Extension. +@code{+simd}: Enables VFP and NEON for Armv8-A. +@code{+crypto}: Enables Cryptography Extensions for Armv8-A, implies +@code{+simd}. +@code{+sb}: Enables Speculation Barrier Instruction for Armv8-A. +@code{+predres}: Enables Execution and Data Prediction Restriction Instruction +for Armv8-A. +@code{+nofp}: Disables all FPU, NEON and Cryptography Extensions. +@code{+nocrypto}: Disables Cryptography Extensions. + +For @code{armv8.1-a}: + +@code{+simd}: Enables VFP and NEON for Armv8.1-A. +@code{+crypto}: Enables Cryptography Extensions for Armv8-A, implies +@code{+simd}. +@code{+sb}: Enables Speculation Barrier Instruction for Armv8-A. +@code{+predres}: Enables Execution and Data Prediction Restriction Instruction +for Armv8-A. +@code{+nofp}: Disables all FPU, NEON and Cryptography Extensions. +@code{+nocrypto}: Disables Cryptography Extensions. + +For @code{armv8.2-a} and @code{armv8.3-a}: + +@code{+simd}: Enables VFP and NEON for Armv8.1-A. +@code{+fp16}: Enables FP16 Extension for Armv8.2-A, implies @code{+simd}. +@code{+fp16fml}: Enables FP16 Floating Point Multiplication Variant Extensions +for Armv8.2-A, implies @code{+fp16}. +@code{+crypto}: Enables Cryptography Extensions for Armv8-A, implies +@code{+simd}. +@code{+dotprod}: Enables Dot Product Extensions for Armv8.2-A, implies +@code{+simd}. +@code{+sb}: Enables Speculation Barrier Instruction for Armv8-A. +@code{+predres}: Enables Execution and Data Prediction Restriction Instruction +for Armv8-A. +@code{+nofp}: Disables all FPU, NEON, Cryptography and Dot Product Extensions. +@code{+nocrypto}: Disables Cryptography Extensions. + +For @code{armv8.4-a}: + +@code{+simd}: Enables VFP and NEON for Armv8.1-A and Dot Product Extensions for +Armv8.2-A. +@code{+fp16}: Enables FP16 Floating Point and Floating Point Multiplication +Variant Extensions for Armv8.2-A, implies @code{+simd}. +@code{+crypto}: Enables Cryptography Extensions for Armv8-A, implies +@code{+simd}. +@code{+sb}: Enables Speculation Barrier Instruction for Armv8-A. +@code{+predres}: Enables Execution and Data Prediction Restriction Instruction +for Armv8-A. +@code{+nofp}: Disables all FPU, NEON, Cryptography and Dot Product Extensions. +@code{+nocryptp}: Disables Cryptography Extensions. + +For @code{armv8.5-a}: + +@code{+simd}: Enables VFP and NEON for Armv8.1-A and Dot Product Extensions for +Armv8.2-A. +@code{+fp16}: Enables FP16 Floating Point and Floating Point Multiplication +Variant Extensions for Armv8.2-A, implies @code{+simd}. +@code{+crypto}: Enables Cryptography Extensions for Armv8-A, implies +@code{+simd}. +@code{+nofp}: Disables all FPU, NEON, Cryptography and Dot Product Extensions. +@code{+nocryptp}: Disables Cryptography Extensions. + @cindex @code{-mfpu=} command-line option, ARM @item -mfpu=@var{floating-point-format} diff --git a/gas/testsuite/gas/arm/armv8-2-fp16-scalar-bad-ext.d b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-bad-ext.d new file mode 100644 index 00000000000..b98e7cf7b24 --- /dev/null +++ b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-bad-ext.d @@ -0,0 +1,4 @@ +#name: Invalid armv8.2-a scalar fp16 +#source: armv8-2-fp16-scalar-bad.s +#as: -march=armv8.2-a+fp16 +#error_output: armv8-2-fp16-scalar-bad.l diff --git a/gas/testsuite/gas/arm/armv8-2-fp16-scalar-ext.d b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-ext.d new file mode 100644 index 00000000000..0b5e4e4861c --- /dev/null +++ b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-ext.d @@ -0,0 +1,75 @@ +#name: ARM v8.2 FP16 support on scalar +#source: armv8-2-fp16-scalar.s +#objdump: -d +#as: -march=armv8.2-a+fp16 +#skip: *-*-pe *-*-wince + +.*: +file format .*arm.* +Disassembly of section .text: + +00000000 : + 0: ee001910 vmov.f16 s0, r1 + 4: ee100990 vmov.f16 r0, s1 + 8: eeb00900 vmov.f16 s0, #0 ; 0x40000000 2.0 + +0000000c