diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 5bcd88ba8feb06177a5a909d4405b59861677e21..89d44a46cad3133259aadd09a3f1063418b09606 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 with SIMD, so to 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 with SIMD, so to 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 with SIMD, so to 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 with SIMD, so to 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 with SIMD, so to 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: Please do not use 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 4fb6cadf93526be4736e38cfcac27aa457df40c9..184d7160a887d3512de50255c17bcbb1ba661667 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 0000000000000000000000000000000000000000..b98e7cf7b24806b77d70cc56d5f4a6bef040394a --- /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 0000000000000000000000000000000000000000..0b5e4e4861c6522e4cc24d63051fad3e9c145939 --- /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