+2017-06-16 Richard Earnshaw <rearnsha@arm.com>
+
+ * config/arm/arm-cpus.in (armv8-a): Add options crc, simd crypto and
+ nofp.
+ (armv8-a+crc): Delete.
+ (armv8.1-a): Add options simd, crypto and nofp.
+ (armv8.2-a): Add options fp16, simd, crypto and nofp.
+ (armv8.2-a+fp16): Delete.
+ (armv8-m.main): Add option dsp.
+ (armv8-m.main+dsp): Delete.
+ (cortex-a8): Add fpu. Add nofp option.
+ (cortex-a9): Add fpu. Add nofp and nosimd options.
+ * config/arm/parsecpu.awk (gen_data): Generate option tables and
+ link to main cpu and architecture data structures.
+ (gen_comm_data): Only put isa attributes from the main architecture
+ in common tables.
+ (option): New statement for architecture and CPU entries.
+ * arm.c (struct cpu_option): New structure.
+ (struct processors): Add entry for options.
+ (arm_unrecognized_feature): New function.
+ (arm_parse_arch_cpu_name): Ignore any characters after the first
+ '+' character.
+ (arm_parse_arch_cpu_feature): New function.
+ (arm_configure_build_target): Separate out any CPU and architecture
+ features and parse separately. Don't error out if -mfpu=auto is
+ used with only an architecture string.
+ (arm_print_asm_arch_directives): New function.
+ (arm_file_start): Call it.
+ * config/arm/arm-cpu-cdata.h: Regenerated.
+ * config/arm/arm-cpu-data.h: Likewise.
+ * config/arm/arm-tables.opt: Likewise.
+
2017-06-16 Richard Earnshaw <rearnsha@arm.com>
* config/arm/elf.h (ASM_SPEC): Only pass -mfpu through to the
"cortex-a8",
{
ISA_ARMv7a,
+ ISA_VFPv3,ISA_NEON,
isa_nobit
},
},
"cortex-a9",
{
ISA_ARMv7a,
+ ISA_VFPv3,ISA_NEON,
isa_nobit
},
},
{
"cortex-a32",
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
isa_nobit
},
},
{
"cortex-a35",
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
isa_nobit
},
},
{
"cortex-a53",
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
isa_nobit
},
},
{
"cortex-a57",
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
isa_nobit
},
},
{
"cortex-a72",
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
isa_nobit
},
},
{
"cortex-a73",
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
isa_nobit
},
},
{
"exynos-m1",
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
isa_nobit
},
},
{
"cortex-a57.cortex-a53",
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
isa_nobit
},
},
{
"cortex-a72.cortex-a53",
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
isa_nobit
},
},
{
"cortex-a73.cortex-a35",
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
isa_nobit
},
},
{
"cortex-a73.cortex-a53",
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
isa_nobit
},
},
{
"cortex-m33",
{
- ISA_ARMv8m_main,isa_bit_ARMv7em,
+ ISA_ARMv8m_main,
isa_nobit
},
},
isa_nobit
},
},
- {
- "armv8-a+crc",
- {
- ISA_ARMv8a,isa_bit_crc32,
- isa_nobit
- },
- },
{
"armv8.1-a",
{
isa_nobit
},
},
- {
- "armv8.2-a+fp16",
- {
- ISA_ARMv8_2a,isa_bit_fp16,
- isa_nobit
- },
- },
{
"armv8-m.base",
{
isa_nobit
},
},
- {
- "armv8-m.main+dsp",
- {
- ISA_ARMv8m_main,isa_bit_ARMv7em,
- isa_nobit
- },
- },
{
"iwmmxt",
{
License along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+static const struct cpu_option cpu_opttab_cortexa8[] = {
+ {
+ "nofp", true,
+ { ISA_NEON,ISA_VFPv3, isa_nobit }
+ },
+ { NULL, false, {isa_nobit}}
+};
+
+static const struct cpu_option cpu_opttab_cortexa9[] = {
+ {
+ "nofp", true,
+ { ISA_NEON,ISA_VFPv3, isa_nobit }
+ },
+ {
+ "nosimd", true,
+ { ISA_NEON, isa_nobit }
+ },
+ { NULL, false, {isa_nobit}}
+};
+
static const struct processors all_cores[] =
{
{
ISA_ARMv2,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv2,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv2,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_slowmul_tune
},
{
ISA_ARMv3m,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv3m,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv3m,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_strongarm_tune
},
{
ISA_ARMv4,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_strongarm_tune
},
{
ISA_ARMv4,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_strongarm_tune
},
{
ISA_ARMv4,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_strongarm_tune
},
{
ISA_ARMv4,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4,isa_bit_mode26,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv4t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv5t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv5t,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv5te,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_ARMv5te,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_ARMv5te,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_ARMv5te,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_ARMv5te,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv5te,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
ISA_ARMv5te,
isa_nobit
},
+ NULL,
&arm_fastmul_tune
},
{
isa_bit_xscale,
isa_nobit
},
+ NULL,
&arm_xscale_tune
},
{
ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,
isa_nobit
},
+ NULL,
&arm_xscale_tune
},
{
ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,isa_bit_iwmmxt2,
isa_nobit
},
+ NULL,
&arm_xscale_tune
},
{
ISA_ARMv5te,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_ARMv5te,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_ARMv5te,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_ARMv5te,
isa_nobit
},
+ NULL,
&arm_fa726te_tune
},
{
ISA_ARMv5tej,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_ARMv5tej,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_ARMv6j,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_VFPv2,ISA_FP_DBL,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_ARMv6kz,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_VFPv2,ISA_FP_DBL,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_ARMv6k,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_VFPv2,ISA_FP_DBL,
isa_nobit
},
+ NULL,
&arm_9e_tune
},
{
ISA_ARMv6t2,
isa_nobit
},
+ NULL,
&arm_v6t2_tune
},
{
ISA_VFPv2,ISA_FP_DBL,
isa_nobit
},
+ NULL,
&arm_v6t2_tune
},
{
ISA_ARMv6m,
isa_nobit
},
+ NULL,
&arm_v6m_tune
},
{
ISA_ARMv6m,
isa_nobit
},
+ NULL,
&arm_v6m_tune
},
{
ISA_ARMv6m,
isa_nobit
},
+ NULL,
&arm_v6m_tune
},
{
ISA_ARMv6m,
isa_nobit
},
+ NULL,
&arm_v6m_tune
},
{
ISA_ARMv6m,
isa_nobit
},
+ NULL,
&arm_v6m_tune
},
{
ISA_ARMv6m,
isa_nobit
},
+ NULL,
&arm_v6m_tune
},
{
ISA_ARMv7a,
isa_nobit
},
+ NULL,
&arm_cortex_tune
},
{
ISA_ARMv7a,
isa_nobit
},
+ NULL,
&arm_cortex_a5_tune
},
{
ISA_ARMv7ve,
isa_nobit
},
+ NULL,
&arm_cortex_a7_tune
},
{
"7A", BASE_ARCH_7A,
{
ISA_ARMv7a,
+ ISA_VFPv3,ISA_NEON,
isa_nobit
},
+ cpu_opttab_cortexa8,
&arm_cortex_a8_tune
},
{
"7A", BASE_ARCH_7A,
{
ISA_ARMv7a,
+ ISA_VFPv3,ISA_NEON,
isa_nobit
},
+ cpu_opttab_cortexa9,
&arm_cortex_a9_tune
},
{
ISA_ARMv7ve,
isa_nobit
},
+ NULL,
&arm_cortex_a12_tune
},
{
ISA_ARMv7ve,
isa_nobit
},
+ NULL,
&arm_cortex_a15_tune
},
{
ISA_ARMv7ve,
isa_nobit
},
+ NULL,
&arm_cortex_a12_tune
},
{
ISA_ARMv7r,
isa_nobit
},
+ NULL,
&arm_cortex_tune
},
{
ISA_ARMv7r,
isa_nobit
},
+ NULL,
&arm_cortex_tune
},
{
isa_bit_adiv,
isa_nobit
},
+ NULL,
&arm_cortex_tune
},
{
isa_bit_adiv,
isa_nobit
},
+ NULL,
&arm_cortex_tune
},
{
isa_bit_adiv,
isa_nobit
},
+ NULL,
&arm_cortex_tune
},
{
isa_quirk_no_volatile_ce,
isa_nobit
},
+ NULL,
&arm_cortex_m7_tune
},
{
ISA_ARMv7em,
isa_nobit
},
+ NULL,
&arm_v7m_tune
},
{
isa_quirk_cm3_ldrd,
isa_nobit
},
+ NULL,
&arm_v7m_tune
},
{
ISA_ARMv7a,
isa_nobit
},
+ NULL,
&arm_marvell_pj4_tune
},
{
ISA_ARMv7ve,
isa_nobit
},
+ NULL,
&arm_cortex_a15_tune
},
{
ISA_ARMv7ve,
isa_nobit
},
+ NULL,
&arm_cortex_a12_tune
},
{
(TF_LDSCHED),
"8A", BASE_ARCH_8A,
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
+ isa_bit_crc32,
isa_nobit
},
+ NULL,
&arm_cortex_a35_tune
},
{
(TF_LDSCHED),
"8A", BASE_ARCH_8A,
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
+ isa_bit_crc32,
isa_nobit
},
+ NULL,
&arm_cortex_a35_tune
},
{
(TF_LDSCHED),
"8A", BASE_ARCH_8A,
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
+ isa_bit_crc32,
isa_nobit
},
+ NULL,
&arm_cortex_a53_tune
},
{
(TF_LDSCHED),
"8A", BASE_ARCH_8A,
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
+ isa_bit_crc32,
isa_nobit
},
+ NULL,
&arm_cortex_a57_tune
},
{
(TF_LDSCHED),
"8A", BASE_ARCH_8A,
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
+ isa_bit_crc32,
isa_nobit
},
+ NULL,
&arm_cortex_a57_tune
},
{
(TF_LDSCHED),
"8A", BASE_ARCH_8A,
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
+ isa_bit_crc32,
isa_nobit
},
+ NULL,
&arm_cortex_a73_tune
},
{
(TF_LDSCHED),
"8A", BASE_ARCH_8A,
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
+ isa_bit_crc32,
isa_nobit
},
+ NULL,
&arm_exynosm1_tune
},
{
ISA_ARMv8a,
isa_nobit
},
+ NULL,
&arm_xgene1_tune
},
{
(TF_LDSCHED),
"8A", BASE_ARCH_8A,
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
+ isa_bit_crc32,
isa_nobit
},
+ NULL,
&arm_cortex_a57_tune
},
{
(TF_LDSCHED),
"8A", BASE_ARCH_8A,
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
+ isa_bit_crc32,
isa_nobit
},
+ NULL,
&arm_cortex_a57_tune
},
{
(TF_LDSCHED),
"8A", BASE_ARCH_8A,
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
+ isa_bit_crc32,
isa_nobit
},
+ NULL,
&arm_cortex_a73_tune
},
{
(TF_LDSCHED),
"8A", BASE_ARCH_8A,
{
- ISA_ARMv8a,isa_bit_crc32,
+ ISA_ARMv8a,
+ isa_bit_crc32,
isa_nobit
},
+ NULL,
&arm_cortex_a73_tune
},
{
ISA_ARMv8m_base,
isa_nobit
},
+ NULL,
&arm_v6m_tune
},
{
(TF_LDSCHED),
"8M_MAIN", BASE_ARCH_8M_MAIN,
{
- ISA_ARMv8m_main,isa_bit_ARMv7em,
+ ISA_ARMv8m_main,
+ isa_bit_ARMv7em,
isa_nobit
},
+ NULL,
&arm_v7m_tune
},
- {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0, {isa_nobit}, NULL}
+ {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0, {isa_nobit}, NULL, NULL}
+};
+
+static const struct cpu_option arch_opttab_armv8_a[] = {
+ {
+ "crc", false,
+ { isa_bit_crc32, isa_nobit }
+ },
+ {
+ "simd", false,
+ { ISA_FP_ARMv8,ISA_NEON, isa_nobit }
+ },
+ {
+ "crypto", false,
+ { ISA_FP_ARMv8,ISA_NEON,ISA_CRYPTO, isa_nobit }
+ },
+ {
+ "nofp", true,
+ { ISA_FP_ARMv8,ISA_NEON,ISA_CRYPTO, isa_nobit }
+ },
+ { NULL, false, {isa_nobit}}
+};
+
+static const struct cpu_option arch_opttab_armv8_1_a[] = {
+ {
+ "simd", false,
+ { ISA_FP_ARMv8,ISA_NEON, isa_nobit }
+ },
+ {
+ "crypto", false,
+ { ISA_FP_ARMv8,ISA_NEON,ISA_CRYPTO, isa_nobit }
+ },
+ {
+ "nofp", true,
+ { ISA_FP_ARMv8,ISA_NEON,ISA_CRYPTO, isa_nobit }
+ },
+ { NULL, false, {isa_nobit}}
+};
+
+static const struct cpu_option arch_opttab_armv8_2_a[] = {
+ {
+ "fp16", false,
+ { isa_bit_fp16,ISA_FP_ARMv8,ISA_NEON, isa_nobit }
+ },
+ {
+ "simd", false,
+ { ISA_FP_ARMv8,ISA_NEON, isa_nobit }
+ },
+ {
+ "crypto", false,
+ { ISA_FP_ARMv8,ISA_NEON,ISA_CRYPTO, isa_nobit }
+ },
+ {
+ "nofp", true,
+ { isa_bit_fp16,ISA_FP_ARMv8,ISA_NEON,ISA_CRYPTO, isa_nobit }
+ },
+ { NULL, false, {isa_nobit}}
+};
+
+static const struct cpu_option arch_opttab_armv8_m_main[] = {
+ {
+ "dsp", false,
+ { isa_bit_ARMv7em, isa_nobit }
+ },
+ { NULL, false, {isa_nobit}}
};
static const struct processors all_architectures[] =
ISA_ARMv2,isa_bit_mode26,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv2,isa_bit_mode26,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv3,isa_bit_mode26,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv3m,isa_bit_mode26,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv4,isa_bit_mode26,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv4t,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv5,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv5t,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv5e,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv5te,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv5tej,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv6,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv6j,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv6k,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv6z,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv6kz,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv6kz,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv6t2,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv6m,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv6m,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv7,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv7a,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv7ve,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv7r,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv7m,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv7em,
isa_nobit
},
+ NULL,
NULL
},
{
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
- },
+ arch_opttab_armv8_a,
NULL
},
{
ISA_ARMv8_1a,
isa_nobit
},
+ arch_opttab_armv8_1_a,
NULL
},
{
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
- },
+ arch_opttab_armv8_2_a,
NULL
},
{
ISA_ARMv8m_base,
isa_nobit
},
+ NULL,
NULL
},
{
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
- },
+ arch_opttab_armv8_m_main,
NULL
},
{
ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,
isa_nobit
},
+ NULL,
NULL
},
{
ISA_ARMv5te,isa_bit_xscale,isa_bit_iwmmxt,isa_bit_iwmmxt2,
isa_nobit
},
+ NULL,
NULL
},
- {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0, {isa_nobit}, NULL}
+ {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0, {isa_nobit}, NULL, NULL}
};
const struct arm_fpu_desc all_fpus[] =
tune flags CO_PROC
base 8A
isa ARMv8a
+ option crc add bit_crc32
+ option simd add FP_ARMv8 NEON
+ option crypto add FP_ARMv8 NEON CRYPTO
+ option nofp remove FP_ARMv8 NEON CRYPTO
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 NEON CRYPTO
+ option nofp remove FP_ARMv8 NEON CRYPTO
end arch armv8.1-a
begin arch armv8.2-a
tune flags CO_PROC
base 8A
isa ARMv8_2a
+ option fp16 add bit_fp16 FP_ARMv8 NEON
+ option simd add FP_ARMv8 NEON
+ option crypto add FP_ARMv8 NEON CRYPTO
+ option nofp remove bit_fp16 FP_ARMv8 NEON CRYPTO
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
tune flags CO_PROC
base 8M_MAIN
isa ARMv8m_main
+ option dsp add 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
# architecture <name>
# [fpu <name>]
# [isa <additional-isa-flags-list>]
+# [option <name> add|remove <isa-list>]*
# [costs <name>]
# end cpu <name>
#
cname cortexa8
tune flags LDSCHED
architecture armv7-a
+ fpu neon-vfpv3
+ option nofp remove NEON VFPv3
costs cortex_a8
end cpu cortex-a8
cname cortexa9
tune flags LDSCHED
architecture armv7-a
+ fpu neon-vfpv3
+ option nofp remove NEON VFPv3
+ option nosimd remove NEON
costs cortex_a9
end cpu cortex-a9
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)
\f
/* Initialization code. */
+struct cpu_option
+{
+ const char *const name;
+ bool remove;
+ const enum isa_feature isa_bits[isa_num_bits];
+};
+
struct processors
{
const char *const name;
unsigned int tune_flags;
const char *arch;
enum base_architecture base_arch;
- enum isa_feature isa_bits[isa_num_bits];
+ const enum isa_feature isa_bits[isa_num_bits];
+ const struct cpu_option* const opttab;
const struct tune_params *const tune;
};
const char *target)
{
const struct processors *entry;
+ const char *end = strchr (target, '+');
+ size_t len = end ? end - target : strlen (target);
+
for (entry = list; entry->name != NULL; entry++)
{
- if (streq (entry->name, target))
+ if (strncmp (entry->name, target, len) == 0
+ && entry->name[len] == '\0')
return entry;
}
return NULL;
}
+/* 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 struct processors *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_option *list = target->opttab; 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. */
+static void
+arm_parse_arch_cpu_features (sbitmap isa, const struct processors *target,
+ const char *opts_in)
+{
+ const char *opts = opts_in;
+
+ if (!opts)
+ return;
+
+ if (!target->opttab)
+ {
+ error_at (input_location, "%s does not take any feature options",
+ target->name);
+ return;
+ }
+
+ while (opts)
+ {
+ gcc_assert (*opts == '+');
+ const struct cpu_option *entry;
+ const char *end = strchr (++opts, '+');
+ size_t len = end ? end - opts : strlen (opts);
+ bool matched = false;
+
+ for (entry = target->opttab; !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;
+ }
+}
+
static sbitmap isa_all_fpubits;
static sbitmap isa_quirkbits;
const struct processors *arm_selected_arch = NULL;
const struct processors *arm_selected_cpu = NULL;
const struct 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_string)
- arm_selected_arch = arm_parse_arch_cpu_name (all_architectures,
- "-march",
- opts->x_arm_arch_string);
+ {
+ arm_selected_arch = arm_parse_arch_cpu_name (all_architectures,
+ "-march",
+ opts->x_arm_arch_string);
+ arch_opts = strchr (opts->x_arm_arch_string, '+');
+ }
+
if (opts_set->x_arm_cpu_string)
{
arm_selected_cpu = arm_parse_arch_cpu_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_string)
- arm_selected_tune = arm_parse_arch_cpu_name (all_cores, "-mtune",
- opts->x_arm_tune_string);
+ {
+ arm_selected_tune = arm_parse_arch_cpu_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_parse_arch_cpu_features (target->isa, arm_selected_arch, arch_opts);
if (arm_selected_cpu)
{
auto_sbitmap cpu_isa (isa_num_bits);
arm_initialize_isa (cpu_isa, arm_selected_cpu->isa_bits);
+ arm_parse_arch_cpu_features (cpu_isa, arm_selected_cpu, cpu_opts);
bitmap_xor (cpu_isa, cpu_isa, target->isa);
/* Ignore any bits that are quirk bits. */
bitmap_and_compl (cpu_isa, cpu_isa, isa_quirkbits);
{
target->core_name = arm_selected_cpu->name;
arm_initialize_isa (target->isa, arm_selected_cpu->isa_bits);
+ arm_parse_arch_cpu_features (target->isa, arm_selected_cpu, cpu_opts);
}
/* If the user did not specify a processor, choose one for them. */
else
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];
+ else /* Validate the features passed to -mtune. */
+ arm_parse_arch_cpu_features (NULL, arm_selected_tune, tune_opts);
/* Finish initializing the target structure. */
target->arch_pp_name = arm_selected_cpu->arch;
(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 struct processors *arch
+ = arm_parse_arch_cpu_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->opttab)
+ return;
+
+ for (const struct cpu_option *opt = arch->opttab; 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)
{
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)
{
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);
}
/* 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)
function gen_data () {
boilerplate("C")
+ ncpus = split (cpu_list, cpus)
+
+ for (n = 1; n <= ncpus; n++) {
+ if (cpus[n] in cpu_opts) {
+ print "static const struct cpu_option 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]] ","
+ print " { " cpu_opt_isa[cpus[n],opts[opt]] ", isa_nobit }"
+ print " },"
+ }
+ print " { NULL, false, {isa_nobit}}"
+ print "};\n"
+ }
+ }
+
print "static const struct processors all_cores[] ="
print "{"
- ncpus = split (cpu_list, cpus)
-
for (n = 1; n <= ncpus; n++) {
print " {"
print " \"" cpus[n] "\","
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])
+ nfeats = split (cpu_arch[cpus[n]], feats, "+")
+ if (! (feats[1] in arch_isa)) {
+ fatal("unknown arch " feats[1] " for cpu " cpus[n])
}
- print " \"" arch_base[cpu_arch[cpus[n]]] "\", BASE_ARCH_" \
- arch_base[cpu_arch[cpus[n]]] ","
+ print " \"" arch_base[feats[1]] "\", BASE_ARCH_" \
+ arch_base[feats[1]] ","
print " {"
- print " " arch_isa[cpu_arch[cpus[n]]] ","
+ 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 " },"
+ if (cpus[n] in cpu_opts) {
+ print " cpu_opttab_" cpu_cnames[cpus[n]] ","
+ } else print " NULL,"
print " &arm_" cpu_cost[cpus[n]] "_tune"
print " },"
}
print " {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0," \
- " {isa_nobit}, NULL}"
+ " {isa_nobit}, NULL, NULL}"
print "};\n"
+ narchs = split (arch_list, archs)
+
+ for (n = 1; n <= narchs; n++) {
+ if (archs[n] in arch_opts) {
+ print "static const struct cpu_option 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]] ","
+ print " { " arch_opt_isa[archs[n],opts[opt]] ", isa_nobit }"
+ print " },"
+ }
+ print " { NULL, false, {isa_nobit}}"
+ print "};\n"
+ }
+ }
+
print "static const struct processors all_architectures[] ="
print "{"
- narchs = split (arch_list, archs)
-
for (n = 1; n <= narchs; n++) {
print " {"
if (! (arch_tune_for[archs[n]] in cpu_cnames)) {
print " " arch_isa[archs[n]] ","
print " isa_nobit"
print " },"
+ if (archs[n] in arch_opts) {
+ print " arch_opttab_" arch_cnames[archs[n]] ","
+ } else print " NULL,"
print " NULL"
print " },"
}
print " {NULL, TARGET_CPU_arm_none, 0, NULL, BASE_ARCH_0," \
- " {isa_nobit}, NULL}"
+ " {isa_nobit}, NULL, NULL}"
print "};\n"
print "const struct arm_fpu_desc all_fpus[] ="
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])
+ # Just truncate the architecture name at the beginning of the
+ # extensions. We don't need any of those here (at present).
+ arch_name = cpu_arch[cpus[n]];
+ sub("+.*", "", arch_name)
+ if (! (arch_name in arch_isa)) {
+ fatal("unknown arch " arch_name " for cpu " cpus[n])
}
print " {"
- print " " arch_isa[cpu_arch[cpus[n]]] ","
+ print " " arch_isa[arch_name] ","
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"
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
}
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
+}
+
/^[ ]*costs / {
if (cpu_name == "") fatal("\"costs\" outside of cpu block")
cpu_cost[cpu_name] = $2