From e74cfd166e5a1a76025c0e34f858747610a3c74d Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Tue, 31 Jan 2006 14:11:13 +0000 Subject: [PATCH] 2006-01-31 Paul Brook Richard Earnshaw * gas/config/tc-arm.c: Use arm_feature_set. (arm_ext_*, arm_arch_full, arm_arch_t2, arm_arch_none, arm_cext_iwmmxt, arm_cext_xscale, arm_cext_maverick, fpu_fpa_ext_v1, fpu_fpa_ext_v2, fpu_vfp_ext_v1xd, fpu_vfp_ext_v1, fpu_vfp_ext_v2): New variables. (insns): Use them. (md_atof, opcode_select, opcode_select, md_assemble, md_assemble, md_begin, arm_parse_extension, arm_parse_cpu, arm_parse_arch, arm_parse_fpu, arm_parse_float_abi, aeabi_set_public_attributes, s_arm_cpu, s_arm_arch, s_arm_fpu): Use macros for accessing CPU feature flags. (arm_legacy_option_table, arm_option_cpu_value_table): New types. (arm_opts): Move old cpu/arch options from here... (arm_legacy_opts): ... to here. (md_parse_option): Search arm_legacy_opts. (arm_cpus, arm_archs, arm_extensions, arm_fpus) (arm_float_abis, arm_eabis): Make const. * include/opcode/arm.h: Use ARM_CPU_FEATURE. (ARM_AEXT_*, FPU_ENDIAN_PURE, FPU_VFP_HARD): New. (arm_feature_set): Change to a structure. (ARM_CPU_HAS_FEATURE, ARM_MERGE_FEATURE_SETS, ARM_CLEAR_FEATURE, ARM_FEATURE): New macros. --- gas/ChangeLog | 21 ++ gas/config/tc-arm.c | 674 ++++++++++++++++++++++----------------- include/opcode/ChangeLog | 9 + include/opcode/arm.h | 160 +++++++--- 4 files changed, 520 insertions(+), 344 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 574533a477d..73da5bf16ab 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,24 @@ +2006-01-31 Paul Brook + Richard Earnshaw + + * config/tc-arm.c: Use arm_feature_set. + (arm_ext_*, arm_arch_full, arm_arch_t2, arm_arch_none, + arm_cext_iwmmxt, arm_cext_xscale, arm_cext_maverick, fpu_fpa_ext_v1, + fpu_fpa_ext_v2, fpu_vfp_ext_v1xd, fpu_vfp_ext_v1, fpu_vfp_ext_v2): + New variables. + (insns): Use them. + (md_atof, opcode_select, opcode_select, md_assemble, md_assemble, + md_begin, arm_parse_extension, arm_parse_cpu, arm_parse_arch, + arm_parse_fpu, arm_parse_float_abi, aeabi_set_public_attributes, + s_arm_cpu, s_arm_arch, s_arm_fpu): Use macros for accessing CPU + feature flags. + (arm_legacy_option_table, arm_option_cpu_value_table): New types. + (arm_opts): Move old cpu/arch options from here... + (arm_legacy_opts): ... to here. + (md_parse_option): Search arm_legacy_opts. + (arm_cpus, arm_archs, arm_extensions, arm_fpus) + (arm_float_abis, arm_eabis): Make const. + 2006-01-25 Bob Wilson * config/tc-xtensa.c (md_apply_fix): Set value to zero for PLT relocs. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 4ea80b9be0d..b010a0a8da4 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -98,23 +98,12 @@ enum arm_float_abi }; /* Types of processor to assemble for. */ -#define ARM_1 ARM_ARCH_V1 -#define ARM_2 ARM_ARCH_V2 -#define ARM_3 ARM_ARCH_V2S -#define ARM_250 ARM_ARCH_V2S -#define ARM_6 ARM_ARCH_V3 -#define ARM_7 ARM_ARCH_V3 -#define ARM_8 ARM_ARCH_V4 -#define ARM_9 ARM_ARCH_V4T -#define ARM_STRONG ARM_ARCH_V4 -#define ARM_CPU_MASK 0x0000000f /* XXX? */ - #ifndef CPU_DEFAULT #if defined __XSCALE__ -#define CPU_DEFAULT (ARM_ARCH_XSCALE) +#define CPU_DEFAULT ARM_ARCH_XSCALE #else #if defined __thumb__ -#define CPU_DEFAULT (ARM_ARCH_V5T) +#define CPU_DEFAULT ARM_ARCH_V5T #endif #endif #endif @@ -139,9 +128,9 @@ enum arm_float_abi #define streq(a, b) (strcmp (a, b) == 0) -static unsigned long cpu_variant; -static unsigned long arm_arch_used; -static unsigned long thumb_arch_used; +static arm_feature_set cpu_variant; +static arm_feature_set arm_arch_used; +static arm_feature_set thumb_arch_used; /* Flags stored in private area of BFD structure. */ static int uses_apcs_26 = FALSE; @@ -153,18 +142,68 @@ static int pic_code = FALSE; /* Variables that we set while parsing command-line options. Once all options have been read we re-process these values to set the real assembly flags. */ -static int legacy_cpu = -1; -static int legacy_fpu = -1; - -static int mcpu_cpu_opt = -1; -static int mcpu_fpu_opt = -1; -static int march_cpu_opt = -1; -static int march_fpu_opt = -1; -static int mfpu_opt = -1; +static const arm_feature_set *legacy_cpu = NULL; +static const arm_feature_set *legacy_fpu = NULL; + +static const arm_feature_set *mcpu_cpu_opt = NULL; +static const arm_feature_set *mcpu_fpu_opt = NULL; +static const arm_feature_set *march_cpu_opt = NULL; +static const arm_feature_set *march_fpu_opt = NULL; +static const arm_feature_set *mfpu_opt = NULL; + +/* Constants for known architecture features. */ +static const arm_feature_set fpu_default = FPU_DEFAULT; +static const arm_feature_set fpu_arch_vfp_v1 = FPU_ARCH_VFP_V1; +static const arm_feature_set fpu_arch_vfp_v2 = FPU_ARCH_VFP_V2; +static const arm_feature_set fpu_arch_fpa = FPU_ARCH_FPA; +static const arm_feature_set fpu_any_hard = FPU_ANY_HARD; +static const arm_feature_set fpu_arch_maverick = FPU_ARCH_MAVERICK; +static const arm_feature_set fpu_endian_pure = FPU_ARCH_ENDIAN_PURE; + +#ifdef CPU_DEFAULT +static const arm_feature_set cpu_default = CPU_DEFAULT; +#endif + +static const arm_feature_set arm_ext_v1 = ARM_FEATURE (ARM_EXT_V1, 0); +static const arm_feature_set arm_ext_v2 = ARM_FEATURE (ARM_EXT_V1, 0); +static const arm_feature_set arm_ext_v2s = ARM_FEATURE (ARM_EXT_V2S, 0); +static const arm_feature_set arm_ext_v3 = ARM_FEATURE (ARM_EXT_V3, 0); +static const arm_feature_set arm_ext_v3m = ARM_FEATURE (ARM_EXT_V3M, 0); +static const arm_feature_set arm_ext_v4 = ARM_FEATURE (ARM_EXT_V4, 0); +static const arm_feature_set arm_ext_v4t = ARM_FEATURE (ARM_EXT_V4T, 0); +static const arm_feature_set arm_ext_v5 = ARM_FEATURE (ARM_EXT_V5, 0); +static const arm_feature_set arm_ext_v4t_5 = + ARM_FEATURE (ARM_EXT_V4T | ARM_EXT_V5, 0); +static const arm_feature_set arm_ext_v5t = ARM_FEATURE (ARM_EXT_V5T, 0); +static const arm_feature_set arm_ext_v5e = ARM_FEATURE (ARM_EXT_V5E, 0); +static const arm_feature_set arm_ext_v5exp = ARM_FEATURE (ARM_EXT_V5ExP, 0); +static const arm_feature_set arm_ext_v5j = ARM_FEATURE (ARM_EXT_V5J, 0); +static const arm_feature_set arm_ext_v6 = ARM_FEATURE (ARM_EXT_V6, 0); +static const arm_feature_set arm_ext_v6k = ARM_FEATURE (ARM_EXT_V6K, 0); +static const arm_feature_set arm_ext_v6z = ARM_FEATURE (ARM_EXT_V6Z, 0); +static const arm_feature_set arm_ext_v6t2 = ARM_FEATURE (ARM_EXT_V6T2, 0); + +static const arm_feature_set arm_arch_any = ARM_ANY; +static const arm_feature_set arm_arch_full = ARM_FEATURE (-1, -1); +static const arm_feature_set arm_arch_t2 = ARM_ARCH_THUMB2; +static const arm_feature_set arm_arch_none = ARM_ARCH_NONE; + +static const arm_feature_set arm_cext_iwmmxt = + ARM_FEATURE (0, ARM_CEXT_IWMMXT); +static const arm_feature_set arm_cext_xscale = + ARM_FEATURE (0, ARM_CEXT_XSCALE); +static const arm_feature_set arm_cext_maverick = + ARM_FEATURE (0, ARM_CEXT_MAVERICK); +static const arm_feature_set fpu_fpa_ext_v1 = ARM_FEATURE (0, FPU_FPA_EXT_V1); +static const arm_feature_set fpu_fpa_ext_v2 = ARM_FEATURE (0, FPU_FPA_EXT_V2); +static const arm_feature_set fpu_vfp_ext_v1xd = + ARM_FEATURE (0, FPU_VFP_EXT_V1xD); +static const arm_feature_set fpu_vfp_ext_v1 = ARM_FEATURE (0, FPU_VFP_EXT_V1); +static const arm_feature_set fpu_vfp_ext_v2 = ARM_FEATURE (0, FPU_VFP_EXT_V2); + static int mfloat_abi_opt = -1; -/* Record user cpu selection for object attributes. - Zero if no default or user specified CPU. */ -static int selected_cpu = -1; +/* Record user cpu selection for object attributes. */ +static arm_feature_set selected_cpu = ARM_ARCH_NONE; /* Must be long enough to hold any of the names in arm_cpus. */ static char selected_cpu_name[16]; #ifdef OBJ_ELF @@ -395,8 +434,8 @@ struct asm_opcode unsigned int tvalue; /* Which architecture variant provides this instruction. */ - unsigned long avariant; - unsigned long tvariant; + const arm_feature_set *avariant; + const arm_feature_set *tvariant; /* Function to call to encode instruction in ARM format. */ void (* aencode) (void); @@ -770,7 +809,7 @@ md_atof (int type, char * litP, int * sizeP) } else { - if (cpu_variant & FPU_ARCH_VFP) + if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure)) for (i = prec - 1; i >= 0; i--) { md_number_to_chars (litP, (valueT) words[i], 2); @@ -1453,7 +1492,7 @@ opcode_select (int width) case 16: if (! thumb_mode) { - if (! (cpu_variant & ARM_EXT_V4T)) + if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t)) as_bad (_("selected processor does not support THUMB opcodes")); thumb_mode = 1; @@ -1467,7 +1506,7 @@ opcode_select (int width) case 32: if (thumb_mode) { - if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T) + if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1)) as_bad (_("selected processor does not support ARM opcodes")); thumb_mode = 0; @@ -8097,14 +8136,15 @@ md_assemble (char *str) if (thumb_mode) { - unsigned long variant; + arm_feature_set variant; variant = cpu_variant; /* Only allow coprocessor instructions on Thumb-2 capable devices. */ - if ((variant & ARM_EXT_V6T2) == 0) - variant &= ARM_ANY; + if (!ARM_CPU_HAS_FEATURE (variant, arm_arch_t2)) + ARM_CLEAR_FEATURE (variant, variant, fpu_any_hard); /* Check that this instruction is supported for this CPU. */ - if (thumb_mode == 1 && (opcode->tvariant & variant) == 0) + if (thumb_mode == 1 + && !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant)) { as_bad (_("selected processor does not support `%s'"), str); return; @@ -8155,19 +8195,21 @@ md_assemble (char *str) return; } } - thumb_arch_used |= opcode->tvariant; + ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, + *opcode->tvariant); /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly - set those bits when Thumb-2 32-bit instuctions are seen. ie. + set those bits when Thumb-2 32-bit instuctions are seen. ie. anything other than bl/blx. This is overly pessimistic for relaxable instructions. */ if ((inst.size == 4 && (inst.instruction & 0xf800e800) != 0xf000e800) || inst.relax) - thumb_arch_used |= ARM_EXT_V6T2; + ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, + arm_ext_v6t2); } else { /* Check that this instruction is supported for this CPU. */ - if ((opcode->avariant & cpu_variant) == 0) + if (!ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant)) { as_bad (_("selected processor does not support `%s'"), str); return; @@ -8189,10 +8231,12 @@ md_assemble (char *str) opcode->aencode (); /* Arm mode bx is marked as both v4T and v5 because it's still required on a hypothetical non-thumb v5 core. */ - if (opcode->avariant == (ARM_EXT_V4T | ARM_EXT_V5)) - arm_arch_used |= ARM_EXT_V4T; + if (ARM_CPU_HAS_FEATURE (*opcode->avariant, arm_ext_v4t) + || ARM_CPU_HAS_FEATURE (*opcode->avariant, arm_ext_v5)) + ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, arm_ext_v4t); else - arm_arch_used |= opcode->avariant; + ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, + *opcode->avariant); } output_inst (str); } @@ -8671,8 +8715,8 @@ static const struct asm_cond conds[] = static const struct asm_opcode insns[] = { -#define ARM_VARIANT ARM_EXT_V1 /* Core ARM Instructions. */ -#define THUMB_VARIANT ARM_EXT_V4T +#define ARM_VARIANT &arm_ext_v1 /* Core ARM Instructions. */ +#define THUMB_VARIANT &arm_ext_v4t tCE(and, 0000000, and, 3, (RR, oRR, SH), arit, t_arit3c), tC3(ands, 0100000, ands, 3, (RR, oRR, SH), arit, t_arit3c), tCE(eor, 0200000, eor, 3, (RR, oRR, SH), arit, t_arit3c), @@ -8742,12 +8786,12 @@ static const struct asm_opcode insns[] = tCE(pop, 8bd0000, pop, 1, (REGLST), push_pop, t_push_pop), #undef THUMB_VARIANT -#define THUMB_VARIANT ARM_EXT_V6 +#define THUMB_VARIANT &arm_ext_v6 TCE(cpy, 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy), /* V1 instructions with no Thumb analogue prior to V6T2. */ #undef THUMB_VARIANT -#define THUMB_VARIANT ARM_EXT_V6T2 +#define THUMB_VARIANT &arm_ext_v6t2 TCE(rsb, 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb), TC3(rsbs, 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb), TCE(teq, 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst), @@ -8779,14 +8823,14 @@ static const struct asm_opcode insns[] = C3(ldmfa, 8100000, 2, (RRw, REGLST), ldmstm), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V2 /* ARM 2 - multiplies. */ +#define ARM_VARIANT &arm_ext_v2 /* ARM 2 - multiplies. */ #undef THUMB_VARIANT -#define THUMB_VARIANT ARM_EXT_V4T +#define THUMB_VARIANT &arm_ext_v4t tCE(mul, 0000090, mul, 3, (RRnpc, RRnpc, oRR), mul, t_mul), tC3(muls, 0100090, muls, 3, (RRnpc, RRnpc, oRR), mul, t_mul), #undef THUMB_VARIANT -#define THUMB_VARIANT ARM_EXT_V6T2 +#define THUMB_VARIANT &arm_ext_v6t2 TCE(mla, 0200090, fb000000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla), C3(mlas, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas), @@ -8800,17 +8844,17 @@ static const struct asm_opcode insns[] = TCE(mrc, e100010, ee100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V2S /* ARM 3 - swp instructions. */ +#define ARM_VARIANT &arm_ext_v2s /* ARM 3 - swp instructions. */ CE(swp, 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn), C3(swpb, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V3 /* ARM 6 Status register instructions. */ +#define ARM_VARIANT &arm_ext_v3 /* ARM 6 Status register instructions. */ TCE(mrs, 10f0000, f3ef8000, 2, (RR, PSR), mrs, t_mrs), TCE(msr, 120f000, f3808000, 2, (PSR, RR_EXi), msr, t_msr), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V3M /* ARM 7M long multiplies. */ +#define ARM_VARIANT &arm_ext_v3m /* ARM 7M long multiplies. */ TCE(smull, 0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull), CM(smull,s, 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull), TCE(umull, 0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull), @@ -8821,9 +8865,9 @@ static const struct asm_opcode insns[] = CM(umlal,s, 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V4 /* ARM Architecture 4. */ +#define ARM_VARIANT &arm_ext_v4 /* ARM Architecture 4. */ #undef THUMB_VARIANT -#define THUMB_VARIANT ARM_EXT_V4T +#define THUMB_VARIANT &arm_ext_v4t tC3(ldrh, 01000b0, ldrh, 2, (RR, ADDR), ldstv4, t_ldst), tC3(strh, 00000b0, strh, 2, (RR, ADDR), ldstv4, t_ldst), tC3(ldrsh, 01000f0, ldrsh, 2, (RR, ADDR), ldstv4, t_ldst), @@ -8832,23 +8876,23 @@ static const struct asm_opcode insns[] = tCM(ld,sb, 01000d0, ldrsb, 2, (RR, ADDR), ldstv4, t_ldst), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V4T|ARM_EXT_V5 +#define ARM_VARIANT &arm_ext_v4t_5 /* ARM Architecture 4T. */ /* Note: bx (and blx) are required on V5, even if the processor does not support Thumb. */ TCE(bx, 12fff10, 4700, 1, (RR), bx, t_bx), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V5 /* ARM Architecture 5T. */ +#define ARM_VARIANT &arm_ext_v5 /* ARM Architecture 5T. */ #undef THUMB_VARIANT -#define THUMB_VARIANT ARM_EXT_V5T +#define THUMB_VARIANT &arm_ext_v5t /* Note: blx has 2 variants; the .value coded here is for BLX(2). Only this variant has conditional execution. */ TCE(blx, 12fff30, 4780, 1, (RR_EXr), blx, t_blx), TUE(bkpt, 1200070, be00, 1, (oIffffb), bkpt, t_bkpt), #undef THUMB_VARIANT -#define THUMB_VARIANT ARM_EXT_V6T2 +#define THUMB_VARIANT &arm_ext_v6t2 TCE(clz, 16f0f10, fab0f080, 2, (RRnpc, RRnpc), rd_rm, t_clz), TUF(ldc2, c100000, fc100000, 3, (RCP, RCN, ADDR), lstc, lstc), TUF(ldc2l, c500000, fc500000, 3, (RCP, RCN, ADDR), lstc, lstc), @@ -8859,7 +8903,7 @@ static const struct asm_opcode insns[] = TUF(mrc2, e100010, fe100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V5ExP /* ARM Architecture 5TExP. */ +#define ARM_VARIANT &arm_ext_v5exp /* ARM Architecture 5TExP. */ TCE(smlabb, 1000080, fb100000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla), TCE(smlatb, 10000a0, fb100020, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla), TCE(smlabt, 10000c0, fb100010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla), @@ -8887,7 +8931,7 @@ static const struct asm_opcode insns[] = TCE(qdsub, 1600050, fa80f0b0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, rd_rm_rn), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V5E /* ARM Architecture 5TE. */ +#define ARM_VARIANT &arm_ext_v5e /* ARM Architecture 5TE. */ TUF(pld, 450f000, f810f000, 1, (ADDR), pld, t_pld), TC3(ldrd, 00000d0, e9500000, 3, (RRnpc, oRRnpc, ADDR), ldrd, t_ldstd), TC3(strd, 00000f0, e9400000, 3, (RRnpc, oRRnpc, ADDR), ldrd, t_ldstd), @@ -8896,13 +8940,13 @@ static const struct asm_opcode insns[] = TCE(mrrc, c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V5J /* ARM Architecture 5TEJ. */ +#define ARM_VARIANT &arm_ext_v5j /* ARM Architecture 5TEJ. */ TCE(bxj, 12fff20, f3c08f00, 1, (RR), bxj, t_bxj), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V6 /* ARM V6. */ +#define ARM_VARIANT &arm_ext_v6 /* ARM V6. */ #undef THUMB_VARIANT -#define THUMB_VARIANT ARM_EXT_V6 +#define THUMB_VARIANT &arm_ext_v6 TUF(cpsie, 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi), TUF(cpsid, 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi), tCE(rev, 6bf0f30, rev, 2, (RRnpc, RRnpc), rd_rm, t_rev), @@ -8915,7 +8959,7 @@ static const struct asm_opcode insns[] = TUF(setend, 1010000, b650, 1, (ENDI), setend, t_setend), #undef THUMB_VARIANT -#define THUMB_VARIANT ARM_EXT_V6T2 +#define THUMB_VARIANT &arm_ext_v6t2 TUF(cps, 1020000, f3af8100, 1, (I31b), imm0, imm0), TCE(ldrex, 1900f9f, e8500f00, 2, (RRnpc, ADDR), ldrex, t_ldrex), TUF(mcrr2, c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c), @@ -9007,16 +9051,16 @@ static const struct asm_opcode insns[] = TCE(usat16, 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V6K +#define ARM_VARIANT &arm_ext_v6k #undef THUMB_VARIANT -#define THUMB_VARIANT ARM_EXT_V6K +#define THUMB_VARIANT &arm_ext_v6k tCE(yield, 320f001, yield, 0, (), noargs, t_hint), tCE(wfe, 320f002, wfe, 0, (), noargs, t_hint), tCE(wfi, 320f003, wfi, 0, (), noargs, t_hint), tCE(sev, 320f004, sev, 0, (), noargs, t_hint), #undef THUMB_VARIANT -#define THUMB_VARIANT ARM_EXT_V6T2 +#define THUMB_VARIANT &arm_ext_v6t2 TCE(ldrexb, 1d00f9f, e8d00f4f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn), TCE(ldrexh, 1f00f9f, e8d00f5f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn), TCE(ldrexd, 1b00f9f, e8d0007f, 3, (RRnpc, oRRnpc, RRnpcb), ldrexd, t_ldrexd), @@ -9026,11 +9070,11 @@ static const struct asm_opcode insns[] = TUF(clrex, 57ff01f, f3bf8f2f, 0, (), noargs, noargs), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V6Z +#define ARM_VARIANT &arm_ext_v6z TCE(smc, 1600070, f7f08000, 1, (EXPi), smc, t_smc), #undef ARM_VARIANT -#define ARM_VARIANT ARM_EXT_V6T2 +#define ARM_VARIANT &arm_ext_v6t2 TCE(bfc, 7c0001f, f36f0000, 3, (RRnpc, I31, I32), bfc, t_bfc), TCE(bfi, 7c00010, f3600000, 4, (RRnpc, RRnpc_I0, I31, I32), bfi, t_bfi), TCE(sbfx, 7a00050, f3400000, 4, (RR, RR, I31, I32), bfx, t_bfx), @@ -9067,7 +9111,7 @@ static const struct asm_opcode insns[] = /* Thumb2 only instructions. */ #undef ARM_VARIANT -#define ARM_VARIANT 0 +#define ARM_VARIANT NULL TCE(addw, 0, f2000000, 3, (RR, RR, EXPi), 0, t_add_sub_w), TCE(subw, 0, f2a00000, 3, (RR, RR, EXPi), 0, t_add_sub_w), @@ -9075,7 +9119,7 @@ static const struct asm_opcode insns[] = TCE(tbh, 0, e8d0f010, 1, (TB), 0, t_tb), #undef ARM_VARIANT -#define ARM_VARIANT FPU_FPA_EXT_V1 /* Core FPA instruction set (V1). */ +#define ARM_VARIANT &fpu_fpa_ext_v1 /* Core FPA instruction set (V1). */ cCE(wfs, e200110, 1, (RR), rd), cCE(rfs, e300110, 1, (RR), rd), cCE(wfc, e400110, 1, (RR), rd), @@ -9507,7 +9551,7 @@ static const struct asm_opcode insns[] = /* Instructions that were new with the real FPA, call them V2. */ #undef ARM_VARIANT -#define ARM_VARIANT FPU_FPA_EXT_V2 +#define ARM_VARIANT &fpu_fpa_ext_v2 cCE(lfm, c100200, 3, (RF, I4b, ADDR), fpa_ldmstm), cCL(lfmfd, c900200, 3, (RF, I4b, ADDR), fpa_ldmstm), cCL(lfmea, d100200, 3, (RF, I4b, ADDR), fpa_ldmstm), @@ -9516,7 +9560,7 @@ static const struct asm_opcode insns[] = cCL(sfmea, c800200, 3, (RF, I4b, ADDR), fpa_ldmstm), #undef ARM_VARIANT -#define ARM_VARIANT FPU_VFP_EXT_V1xD /* VFP V1xD (single precision). */ +#define ARM_VARIANT &fpu_vfp_ext_v1xd /* VFP V1xD (single precision). */ /* Moves and type conversions. */ cCE(fcpys, eb00a40, 2, (RVS, RVS), vfp_sp_monadic), cCE(fmrs, e100a10, 2, (RR, RVS), vfp_reg_from_sp), @@ -9574,7 +9618,7 @@ static const struct asm_opcode insns[] = cCE(fcmpezs, eb50ac0, 1, (RVS), vfp_sp_compare_z), #undef ARM_VARIANT -#define ARM_VARIANT FPU_VFP_EXT_V1 /* VFP V1 (Double precision). */ +#define ARM_VARIANT &fpu_vfp_ext_v1 /* VFP V1 (Double precision). */ /* Moves and type conversions. */ cCE(fcpyd, eb00b40, 2, (RVD, RVD), rd_rm), cCE(fcvtds, eb70ac0, 2, (RVD, RVS), vfp_dp_sp_cvt), @@ -9625,14 +9669,14 @@ static const struct asm_opcode insns[] = cCE(fcmpezd, eb50bc0, 1, (RVD), rd), #undef ARM_VARIANT -#define ARM_VARIANT FPU_VFP_EXT_V2 +#define ARM_VARIANT &fpu_vfp_ext_v2 cCE(fmsrr, c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2), cCE(fmrrs, c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2), cCE(fmdrr, c400b10, 3, (RVD, RR, RR), rm_rd_rn), cCE(fmrrd, c500b10, 3, (RR, RR, RVD), rd_rn_rm), #undef ARM_VARIANT -#define ARM_VARIANT ARM_CEXT_XSCALE /* Intel XScale extensions. */ +#define ARM_VARIANT &arm_cext_xscale /* Intel XScale extensions. */ cCE(mia, e200010, 3, (RXA, RRnpc, RRnpc), xsc_mia), cCE(miaph, e280010, 3, (RXA, RRnpc, RRnpc), xsc_mia), cCE(miabb, e2c0010, 3, (RXA, RRnpc, RRnpc), xsc_mia), @@ -9643,7 +9687,7 @@ static const struct asm_opcode insns[] = cCE(mra, c500000, 3, (RRnpc, RRnpc, RXA), xsc_mra), #undef ARM_VARIANT -#define ARM_VARIANT ARM_CEXT_IWMMXT /* Intel Wireless MMX technology. */ +#define ARM_VARIANT &arm_cext_iwmmxt /* Intel Wireless MMX technology. */ cCE(tandcb, e13f130, 1, (RR), iwmmxt_tandorc), cCE(tandch, e53f130, 1, (RR), iwmmxt_tandorc), cCE(tandcw, e93f130, 1, (RR), iwmmxt_tandorc), @@ -9808,7 +9852,7 @@ static const struct asm_opcode insns[] = cCE(wzero, e300000, 1, (RIWR), iwmmxt_wzero), #undef ARM_VARIANT -#define ARM_VARIANT ARM_CEXT_MAVERICK /* Cirrus Maverick instructions. */ +#define ARM_VARIANT &arm_cext_maverick /* Cirrus Maverick instructions. */ cCE(cfldrs, c100400, 2, (RMF, ADDR), rd_cpaddr), cCE(cfldrd, c500400, 2, (RMD, ADDR), rd_cpaddr), cCE(cfldr32, c100500, 2, (RMFX, ADDR), rd_cpaddr), @@ -12393,63 +12437,63 @@ md_begin (void) -mcpu= over -march= if both are set (as for GCC); and we prefer -mfpu= over any other way of setting the floating point unit. Use of legacy options with new options are faulted. */ - if (legacy_cpu != -1) + if (legacy_cpu) { - if (mcpu_cpu_opt != -1 || march_cpu_opt != -1) + if (mcpu_cpu_opt || march_cpu_opt) as_bad (_("use of old and new-style options to set CPU type")); mcpu_cpu_opt = legacy_cpu; } - else if (mcpu_cpu_opt == -1) + else if (!mcpu_cpu_opt) mcpu_cpu_opt = march_cpu_opt; - if (legacy_fpu != -1) + if (legacy_fpu) { - if (mfpu_opt != -1) + if (mfpu_opt) as_bad (_("use of old and new-style options to set FPU type")); mfpu_opt = legacy_fpu; } - else if (mfpu_opt == -1) + else if (!mfpu_opt) { #if !(defined (TE_LINUX) || defined (TE_NetBSD) || defined (TE_VXWORKS)) /* Some environments specify a default FPU. If they don't, infer it from the processor. */ - if (mcpu_fpu_opt != -1) + if (mcpu_fpu_opt) mfpu_opt = mcpu_fpu_opt; else mfpu_opt = march_fpu_opt; #else - mfpu_opt = FPU_DEFAULT; + mfpu_opt = &fpu_default; #endif } - if (mfpu_opt == -1) + if (!mfpu_opt) { - if (mcpu_cpu_opt == -1) - mfpu_opt = FPU_DEFAULT; - else if (mcpu_cpu_opt & ARM_EXT_V5) - mfpu_opt = FPU_ARCH_VFP_V2; + if (!mcpu_cpu_opt) + mfpu_opt = &fpu_default; + else if (ARM_CPU_HAS_FEATURE (*mcpu_fpu_opt, arm_ext_v5)) + mfpu_opt = &fpu_arch_vfp_v2; else - mfpu_opt = FPU_ARCH_FPA; + mfpu_opt = &fpu_arch_fpa; } #ifdef CPU_DEFAULT - if (mcpu_cpu_opt == -1) - selected_cpu = mcpu_cpu_opt = CPU_DEFAULT; -#else - if (mcpu_cpu_opt == -1) + if (!mcpu_cpu_opt) { - mcpu_cpu_opt = ARM_ANY; - selected_cpu = 0; + mcpu_cpu_opt = &cpu_default; + selected_cpu = cpu_default; } +#else + if (mcpu_cpu_opt) + selected_cpu = *mcpu_cpu_opt; else - selected_cpu = mcpu_cpu_opt; + mcpu_cpu_opt = &arm_arch_any; #endif - cpu_variant = mcpu_cpu_opt | mfpu_opt; + ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt); - arm_arch_used = thumb_arch_used = 0; + arm_arch_used = thumb_arch_used = arm_arch_none; #if defined OBJ_COFF || defined OBJ_ELF { @@ -12467,8 +12511,7 @@ md_begin (void) if (support_interwork) flags |= F_INTERWORK; if (uses_apcs_float) flags |= F_APCS_FLOAT; if (pic_code) flags |= F_PIC; - if ((cpu_variant & FPU_ANY) == FPU_NONE - || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only. */ + if (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_any_hard)) flags |= F_SOFT_FLOAT; switch (mfloat_abi_opt) @@ -12484,12 +12527,12 @@ md_begin (void) break; } - /* Using VFP conventions (even if soft-float). */ - if (cpu_variant & FPU_VFP_EXT_NONE) + /* Using pure-endian doubles (even if soft-float). */ + if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure)) flags |= F_VFP_FLOAT; #if defined OBJ_ELF - if (cpu_variant & FPU_ARCH_MAVERICK) + if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_maverick)) flags |= EF_ARM_MAVERICK_FLOAT; break; @@ -12524,50 +12567,38 @@ md_begin (void) #endif /* Record the CPU type as well. */ - switch (cpu_variant & ARM_CPU_MASK) - { - case ARM_2: - mach = bfd_mach_arm_2; - break; - - case ARM_3: /* Also ARM_250. */ - mach = bfd_mach_arm_2a; - break; - - case ARM_6: /* Also ARM_7. */ - mach = bfd_mach_arm_3; - break; - - default: - mach = bfd_mach_arm_unknown; - break; - } - - /* Catch special cases. */ - if (cpu_variant & ARM_CEXT_IWMMXT) + if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt)) mach = bfd_mach_arm_iWMMXt; - else if (cpu_variant & ARM_CEXT_XSCALE) + else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_xscale)) mach = bfd_mach_arm_XScale; - else if (cpu_variant & ARM_CEXT_MAVERICK) + else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_maverick)) mach = bfd_mach_arm_ep9312; - else if (cpu_variant & ARM_EXT_V5E) + else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5e)) mach = bfd_mach_arm_5TE; - else if (cpu_variant & ARM_EXT_V5) + else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5)) { - if (cpu_variant & ARM_EXT_V4T) + if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t)) mach = bfd_mach_arm_5T; else mach = bfd_mach_arm_5; } - else if (cpu_variant & ARM_EXT_V4) + else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4)) { - if (cpu_variant & ARM_EXT_V4T) + if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t)) mach = bfd_mach_arm_4T; else mach = bfd_mach_arm_4; } - else if (cpu_variant & ARM_EXT_V3M) + else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3m)) mach = bfd_mach_arm_3M; + else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3)) + mach = bfd_mach_arm_3; + else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2s)) + mach = bfd_mach_arm_2a; + else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2)) + mach = bfd_mach_arm_2; + else + mach = bfd_mach_arm_unknown; bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach); } @@ -12689,125 +12720,137 @@ struct arm_option_table arm_opts[] = /* These are recognized by the assembler, but have no affect on code. */ {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL}, {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL}, + {NULL, NULL, NULL, 0, NULL} +}; + +struct arm_legacy_option_table +{ + char *option; /* Option name to match. */ + const arm_feature_set **var; /* Variable to change. */ + const arm_feature_set value; /* What to change it to. */ + char *deprecated; /* If non-null, print this message. */ +}; +const struct arm_legacy_option_table arm_legacy_opts[] = +{ /* DON'T add any new processors to this list -- we want the whole list to go away... Add them to the processors table instead. */ - {"marm1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")}, - {"m1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")}, - {"marm2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")}, - {"m2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")}, - {"marm250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")}, - {"m250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")}, - {"marm3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")}, - {"m3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")}, - {"marm6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")}, - {"m6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")}, - {"marm600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")}, - {"m600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")}, - {"marm610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")}, - {"m610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")}, - {"marm620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")}, - {"m620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")}, - {"marm7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")}, - {"m7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")}, - {"marm70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")}, - {"m70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")}, - {"marm700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")}, - {"m700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")}, - {"marm700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")}, - {"m700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")}, - {"marm710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")}, - {"m710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")}, - {"marm710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")}, - {"m710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")}, - {"marm720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")}, - {"m720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")}, - {"marm7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")}, - {"m7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")}, - {"marm7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")}, - {"m7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")}, - {"marm7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")}, - {"m7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")}, - {"marm7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")}, - {"m7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")}, - {"marm7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")}, - {"m7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")}, - {"marm7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")}, - {"m7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")}, - {"marm7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")}, - {"m7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")}, - {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")}, - {"m7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")}, - {"marm7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")}, - {"m7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")}, - {"marm7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")}, - {"m7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")}, - {"marm710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")}, - {"m710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")}, - {"marm720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")}, - {"m720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")}, - {"marm740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")}, - {"m740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")}, - {"marm8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")}, - {"m8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")}, - {"marm810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")}, - {"m810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")}, - {"marm9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")}, - {"m9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")}, - {"marm9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")}, - {"m9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")}, - {"marm920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")}, - {"m920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")}, - {"marm940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")}, - {"m940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")}, - {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")}, - {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4, + {"marm1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")}, + {"m1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")}, + {"marm2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")}, + {"m2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")}, + {"marm250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")}, + {"m250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")}, + {"marm3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")}, + {"m3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")}, + {"marm6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")}, + {"m6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")}, + {"marm600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")}, + {"m600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")}, + {"marm610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")}, + {"m610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")}, + {"marm620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")}, + {"m620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")}, + {"marm7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")}, + {"m7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")}, + {"marm70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")}, + {"m70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")}, + {"marm700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")}, + {"m700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")}, + {"marm700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")}, + {"m700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")}, + {"marm710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")}, + {"m710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")}, + {"marm710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")}, + {"m710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")}, + {"marm720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")}, + {"m720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")}, + {"marm7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")}, + {"m7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")}, + {"marm7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")}, + {"m7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")}, + {"marm7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")}, + {"m7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")}, + {"marm7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")}, + {"m7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")}, + {"marm7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")}, + {"m7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")}, + {"marm7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")}, + {"m7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")}, + {"marm7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")}, + {"m7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")}, + {"marm7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")}, + {"m7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")}, + {"marm7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")}, + {"m7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")}, + {"marm7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")}, + {"m7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")}, + {"marm710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")}, + {"m710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")}, + {"marm720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")}, + {"m720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")}, + {"marm740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")}, + {"m740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")}, + {"marm8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")}, + {"m8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")}, + {"marm810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")}, + {"m810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")}, + {"marm9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")}, + {"m9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")}, + {"marm9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")}, + {"m9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")}, + {"marm920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")}, + {"m920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")}, + {"marm940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")}, + {"m940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")}, + {"mstrongarm", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")}, + {"mstrongarm110", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm110")}, - {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4, + {"mstrongarm1100", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm1100")}, - {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4, + {"mstrongarm1110", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm1110")}, - {"mxscale", NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")}, - {"miwmmxt", NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")}, - {"mall", NULL, &legacy_cpu, ARM_ANY, N_("use -mcpu=all")}, + {"mxscale", &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")}, + {"miwmmxt", &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")}, + {"mall", &legacy_cpu, ARM_ANY, N_("use -mcpu=all")}, /* Architecture variants -- don't add any more to this list either. */ - {"mv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")}, - {"marmv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")}, - {"mv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")}, - {"marmv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")}, - {"mv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")}, - {"marmv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")}, - {"mv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")}, - {"marmv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")}, - {"mv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")}, - {"marmv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")}, - {"mv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")}, - {"marmv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")}, - {"mv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")}, - {"marmv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")}, - {"mv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")}, - {"marmv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")}, - {"mv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")}, - {"marmv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")}, + {"mv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")}, + {"marmv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")}, + {"mv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")}, + {"marmv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")}, + {"mv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")}, + {"marmv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")}, + {"mv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")}, + {"marmv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")}, + {"mv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")}, + {"marmv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")}, + {"mv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")}, + {"marmv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")}, + {"mv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")}, + {"marmv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")}, + {"mv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")}, + {"marmv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")}, + {"mv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")}, + {"marmv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")}, /* Floating point variants -- don't add any more to this list either. */ - {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")}, - {"mfpa10", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")}, - {"mfpa11", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")}, - {"mno-fpu", NULL, &legacy_fpu, 0, + {"mfpe-old", &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")}, + {"mfpa10", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")}, + {"mfpa11", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")}, + {"mno-fpu", &legacy_fpu, ARM_ARCH_NONE, N_("use either -mfpu=softfpa or -mfpu=softvfp")}, - {NULL, NULL, NULL, 0, NULL} + {NULL, NULL, ARM_ARCH_NONE, NULL} }; struct arm_cpu_option_table { char *name; - int value; + const arm_feature_set value; /* For some CPUs we assume an FPU unless the user explicitly sets -mfpu=... */ - int default_fpu; + const arm_feature_set default_fpu; /* The canonical name of the CPU, or NULL to use NAME converted to upper case. */ const char *canonical_name; @@ -12815,7 +12858,7 @@ struct arm_cpu_option_table /* This list should, at a minimum, contain all the cpu names recognized by GCC. */ -static struct arm_cpu_option_table arm_cpus[] = +static const struct arm_cpu_option_table arm_cpus[] = { {"all", ARM_ANY, FPU_ARCH_FPA, NULL}, {"arm1", ARM_ARCH_V1, FPU_ARCH_FPA, NULL}, @@ -12900,20 +12943,20 @@ static struct arm_cpu_option_table arm_cpus[] = {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2, NULL}, {"i80200", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL}, /* Maverick */ - {"ep9312", ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK, "ARM920T"}, - {NULL, 0, 0, NULL} + {"ep9312", ARM_FEATURE(ARM_AEXT_V4T, ARM_CEXT_MAVERICK), FPU_ARCH_MAVERICK, "ARM920T"}, + {NULL, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL} }; struct arm_arch_option_table { char *name; - int value; - int default_fpu; + const arm_feature_set value; + const arm_feature_set default_fpu; }; /* This list should, at a minimum, contain all the architecture names recognized by GCC. */ -static struct arm_arch_option_table arm_archs[] = +static const struct arm_arch_option_table arm_archs[] = { {"all", ARM_ANY, FPU_ARCH_FPA}, {"armv1", ARM_ARCH_V1, FPU_ARCH_FPA}, @@ -12943,27 +12986,27 @@ static struct arm_arch_option_table arm_archs[] = {"armv6zkt2", ARM_ARCH_V6ZKT2, FPU_ARCH_VFP}, {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP}, {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP}, - {NULL, 0, 0} + {NULL, ARM_ARCH_NONE, ARM_ARCH_NONE} }; /* ISA extensions in the co-processor space. */ -struct arm_option_value_table +struct arm_option_cpu_value_table { char *name; - int value; + const arm_feature_set value; }; -static struct arm_option_value_table arm_extensions[] = +static const struct arm_option_cpu_value_table arm_extensions[] = { - {"maverick", ARM_CEXT_MAVERICK}, - {"xscale", ARM_CEXT_XSCALE}, - {"iwmmxt", ARM_CEXT_IWMMXT}, - {NULL, 0} + {"maverick", ARM_FEATURE (0, ARM_CEXT_MAVERICK)}, + {"xscale", ARM_FEATURE (0, ARM_CEXT_XSCALE)}, + {"iwmmxt", ARM_FEATURE (0, ARM_CEXT_IWMMXT)}, + {NULL, ARM_ARCH_NONE} }; /* This list should, at a minimum, contain all the fpu names recognized by GCC. */ -static struct arm_option_value_table arm_fpus[] = +static const struct arm_option_cpu_value_table arm_fpus[] = { {"softfpa", FPU_NONE}, {"fpe", FPU_ARCH_FPE}, @@ -12985,24 +13028,30 @@ static struct arm_option_value_table arm_fpus[] = {"arm1136jfs", FPU_ARCH_VFP_V2}, {"arm1136jf-s", FPU_ARCH_VFP_V2}, {"maverick", FPU_ARCH_MAVERICK}, - {NULL, 0} + {NULL, ARM_ARCH_NONE} +}; + +struct arm_option_value_table +{ + char *name; + long value; }; -static struct arm_option_value_table arm_float_abis[] = +static const struct arm_option_value_table arm_float_abis[] = { {"hard", ARM_FLOAT_ABI_HARD}, {"softfp", ARM_FLOAT_ABI_SOFTFP}, {"soft", ARM_FLOAT_ABI_SOFT}, - {NULL, 0} + {NULL, 0} }; #ifdef OBJ_ELF /* We only know how to output GNU and ver 4 (AAELF) formats. */ -static struct arm_option_value_table arm_eabis[] = +static const struct arm_option_value_table arm_eabis[] = { {"gnu", EF_ARM_EABI_UNKNOWN}, {"4", EF_ARM_EABI_VER4}, - {NULL, 0} + {NULL, 0} }; #endif @@ -13015,11 +13064,17 @@ struct arm_long_option_table }; static int -arm_parse_extension (char * str, int * opt_p) +arm_parse_extension (char * str, const arm_feature_set **opt_p) { + arm_feature_set *ext_set = xmalloc (sizeof (arm_feature_set)); + + /* Copy the feature set, so that we can modify it. */ + *ext_set = **opt_p; + *opt_p = ext_set; + while (str != NULL && *str != 0) { - struct arm_option_value_table * opt; + const struct arm_option_cpu_value_table * opt; char * ext; int optlen; @@ -13046,7 +13101,7 @@ arm_parse_extension (char * str, int * opt_p) for (opt = arm_extensions; opt->name != NULL; opt++) if (strncmp (opt->name, str, optlen) == 0) { - *opt_p |= opt->value; + ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->value); break; } @@ -13065,7 +13120,7 @@ arm_parse_extension (char * str, int * opt_p) static int arm_parse_cpu (char * str) { - struct arm_cpu_option_table * opt; + const struct arm_cpu_option_table * opt; char * ext = strchr (str, '+'); int optlen; @@ -13083,8 +13138,8 @@ arm_parse_cpu (char * str) for (opt = arm_cpus; opt->name != NULL; opt++) if (strncmp (opt->name, str, optlen) == 0) { - mcpu_cpu_opt = opt->value; - mcpu_fpu_opt = opt->default_fpu; + mcpu_cpu_opt = &opt->value; + mcpu_fpu_opt = &opt->default_fpu; if (opt->canonical_name) strcpy(selected_cpu_name, opt->canonical_name); else @@ -13108,7 +13163,7 @@ arm_parse_cpu (char * str) static int arm_parse_arch (char * str) { - struct arm_arch_option_table *opt; + const struct arm_arch_option_table *opt; char *ext = strchr (str, '+'); int optlen; @@ -13126,8 +13181,8 @@ arm_parse_arch (char * str) for (opt = arm_archs; opt->name != NULL; opt++) if (streq (opt->name, str)) { - march_cpu_opt = opt->value; - march_fpu_opt = opt->default_fpu; + march_cpu_opt = &opt->value; + march_fpu_opt = &opt->default_fpu; strcpy(selected_cpu_name, opt->name); if (ext != NULL) @@ -13143,12 +13198,12 @@ arm_parse_arch (char * str) static int arm_parse_fpu (char * str) { - struct arm_option_value_table * opt; + const struct arm_option_cpu_value_table * opt; for (opt = arm_fpus; opt->name != NULL; opt++) if (streq (opt->name, str)) { - mfpu_opt = opt->value; + mfpu_opt = &opt->value; return 1; } @@ -13159,7 +13214,7 @@ arm_parse_fpu (char * str) static int arm_parse_float_abi (char * str) { - struct arm_option_value_table * opt; + const struct arm_option_value_table * opt; for (opt = arm_float_abis; opt->name != NULL; opt++) if (streq (opt->name, str)) @@ -13176,7 +13231,7 @@ arm_parse_float_abi (char * str) static int arm_parse_eabi (char * str) { - struct arm_option_value_table *opt; + const struct arm_option_value_table *opt; for (opt = arm_eabis; opt->name != NULL; opt++) if (streq (opt->name, str)) @@ -13210,6 +13265,7 @@ int md_parse_option (int c, char * arg) { struct arm_option_table *opt; + const struct arm_legacy_option_table *fopt; struct arm_long_option_table *lopt; switch (c) @@ -13252,6 +13308,26 @@ md_parse_option (int c, char * arg) } } + for (fopt = arm_legacy_opts; fopt->option != NULL; fopt++) + { + if (c == fopt->option[0] + && ((arg == NULL && fopt->option[1] == 0) + || streq (arg, fopt->option + 1))) + { +#if WARN_DEPRECATED + /* If the option is deprecated, tell the user. */ + if (fopt->deprecated != NULL) + as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, + arg ? arg : "", _(fopt->deprecated)); +#endif + + if (fopt->var != NULL) + *fopt->var = &fopt->value; + + return 1; + } + } + for (lopt = arm_long_opts; lopt->option != NULL; lopt++) { /* These options are expected to have an argument. */ @@ -13312,26 +13388,29 @@ static void aeabi_set_public_attributes (void) { int arch; - int flags; + arm_feature_set flags; /* Choose the architecture based on the capabilities of the requested cpu (if any) and/or the instructions actually used. */ - flags = selected_cpu | mfpu_opt | arm_arch_used | thumb_arch_used; - if (flags & ARM_EXT_V6T2) + ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used); + ARM_MERGE_FEATURE_SETS (flags, flags, *mfpu_opt); + ARM_MERGE_FEATURE_SETS (flags, flags, selected_cpu); + if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v6t2)) arch = 8; - else if (flags & ARM_EXT_V6Z) + else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v6z)) arch = 7; - else if (flags & ARM_EXT_V6K) + else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v6k)) arch = 9; - else if (flags & ARM_EXT_V6) + else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v6)) arch = 6; - else if (flags & ARM_EXT_V5E) + else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v5e)) arch = 4; - else if (flags & (ARM_EXT_V5 | ARM_EXT_V5T)) + else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v5) + || ARM_CPU_HAS_FEATURE (flags, arm_ext_v5t)) arch = 3; - else if (flags & ARM_EXT_V4T) + else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)) arch = 2; - else if (flags & ARM_EXT_V4) + else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4)) arch = 1; else arch = 0; @@ -13355,19 +13434,22 @@ aeabi_set_public_attributes (void) /* Tag_CPU_arch. */ elf32_arm_add_eabi_attr_int (stdoutput, 6, arch); /* Tag_ARM_ISA_use. */ - if (arm_arch_used) + if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_full)) elf32_arm_add_eabi_attr_int (stdoutput, 8, 1); /* Tag_THUMB_ISA_use. */ - if (thumb_arch_used) + if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_full)) elf32_arm_add_eabi_attr_int (stdoutput, 9, - (thumb_arch_used & ARM_EXT_V6T2) ? 2 : 1); + ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_t2) ? 2 : 1); /* Tag_VFP_arch. */ - if ((arm_arch_used | thumb_arch_used) & FPU_ARCH_VFP_V2) + if (ARM_CPU_HAS_FEATURE (thumb_arch_used, fpu_arch_vfp_v2) + || ARM_CPU_HAS_FEATURE (arm_arch_used, fpu_arch_vfp_v2)) elf32_arm_add_eabi_attr_int (stdoutput, 10, 2); - else if ((arm_arch_used | thumb_arch_used) & FPU_ARCH_VFP_V1) + else if (ARM_CPU_HAS_FEATURE (thumb_arch_used, fpu_arch_vfp_v1) + || ARM_CPU_HAS_FEATURE (arm_arch_used, fpu_arch_vfp_v1)) elf32_arm_add_eabi_attr_int (stdoutput, 10, 1); /* Tag_WMMX_arch. */ - if ((arm_arch_used | thumb_arch_used) & ARM_CEXT_IWMMXT) + if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_cext_iwmmxt) + || ARM_CPU_HAS_FEATURE (arm_arch_used, arm_cext_iwmmxt)) elf32_arm_add_eabi_attr_int (stdoutput, 11, 1); } @@ -13398,7 +13480,7 @@ arm_md_end (void) static void s_arm_cpu (int ignored ATTRIBUTE_UNUSED) { - struct arm_cpu_option_table *opt; + const struct arm_cpu_option_table *opt; char *name; char saved_char; @@ -13412,8 +13494,8 @@ s_arm_cpu (int ignored ATTRIBUTE_UNUSED) for (opt = arm_cpus + 1; opt->name != NULL; opt++) if (streq (opt->name, name)) { - mcpu_cpu_opt = opt->value; - selected_cpu = mcpu_cpu_opt; + mcpu_cpu_opt = &opt->value; + selected_cpu = opt->value; if (opt->canonical_name) strcpy(selected_cpu_name, opt->canonical_name); else @@ -13423,7 +13505,7 @@ s_arm_cpu (int ignored ATTRIBUTE_UNUSED) selected_cpu_name[i] = TOUPPER (opt->name[i]); selected_cpu_name[i] = 0; } - cpu_variant = mcpu_cpu_opt | mfpu_opt; + ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt); *input_line_pointer = saved_char; demand_empty_rest_of_line (); return; @@ -13439,7 +13521,7 @@ s_arm_cpu (int ignored ATTRIBUTE_UNUSED) static void s_arm_arch (int ignored ATTRIBUTE_UNUSED) { - struct arm_arch_option_table *opt; + const struct arm_arch_option_table *opt; char saved_char; char *name; @@ -13453,10 +13535,10 @@ s_arm_arch (int ignored ATTRIBUTE_UNUSED) for (opt = arm_archs + 1; opt->name != NULL; opt++) if (streq (opt->name, name)) { - mcpu_cpu_opt = opt->value; - selected_cpu = mcpu_cpu_opt; + mcpu_cpu_opt = &opt->value; + selected_cpu = opt->value; strcpy(selected_cpu_name, opt->name); - cpu_variant = mcpu_cpu_opt | mfpu_opt; + ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt); *input_line_pointer = saved_char; demand_empty_rest_of_line (); return; @@ -13473,7 +13555,7 @@ s_arm_arch (int ignored ATTRIBUTE_UNUSED) static void s_arm_fpu (int ignored ATTRIBUTE_UNUSED) { - struct arm_option_value_table *opt; + const struct arm_option_cpu_value_table *opt; char saved_char; char *name; @@ -13486,8 +13568,8 @@ s_arm_fpu (int ignored ATTRIBUTE_UNUSED) for (opt = arm_fpus; opt->name != NULL; opt++) if (streq (opt->name, name)) { - mfpu_opt = opt->value; - cpu_variant = mcpu_cpu_opt | mfpu_opt; + mfpu_opt = &opt->value; + ARM_MERGE_FEATURE_SETS (cpu_variant, *mcpu_cpu_opt, *mfpu_opt); *input_line_pointer = saved_char; demand_empty_rest_of_line (); return; diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 8ec83409e18..bb8fe767e0c 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,12 @@ +2006-01-31 Paul Brook + Richard Earnshaw + + * arm.h: Use ARM_CPU_FEATURE. + (ARM_AEXT_*, FPU_ENDIAN_PURE, FPU_VFP_HARD): New. + (arm_feature_set): Change to a structure. + (ARM_CPU_HAS_FEATURE, ARM_MERGE_FEATURE_SETS, ARM_CLEAR_FEATURE, + ARM_FEATURE): New macros. + 2005-12-07 Hans-Peter Nilsson * cris.h (MOVE_M_TO_PREG_OPCODE, MOVE_M_TO_PREG_ZBITS) diff --git a/include/opcode/arm.h b/include/opcode/arm.h index d98f038c923..97312b63fb3 100644 --- a/include/opcode/arm.h +++ b/include/opcode/arm.h @@ -37,65 +37,129 @@ #define ARM_EXT_V6T2 0x00008000 /* Thumb-2. */ /* Co-processor space extensions. */ -#define ARM_CEXT_XSCALE 0x00800000 /* Allow MIA etc. */ -#define ARM_CEXT_MAVERICK 0x00400000 /* Use Cirrus/DSP coprocessor. */ -#define ARM_CEXT_IWMMXT 0x00200000 /* Intel Wireless MMX technology coprocessor. */ +#define ARM_CEXT_XSCALE 0x00000001 /* Allow MIA etc. */ +#define ARM_CEXT_MAVERICK 0x00000002 /* Use Cirrus/DSP coprocessor. */ +#define ARM_CEXT_IWMMXT 0x00000004 /* Intel Wireless MMX technology coprocessor. */ + +#define FPU_ENDIAN_PURE 0x80000000 /* Pure-endian doubles. */ +#define FPU_ENDIAN_BIG 0 /* Double words-big-endian. */ +#define FPU_FPA_EXT_V1 0x40000000 /* Base FPA instruction set. */ +#define FPU_FPA_EXT_V2 0x20000000 /* LFM/SFM. */ +#define FPU_MAVERICK 0x10000000 /* Cirrus Maverick. */ +#define FPU_VFP_EXT_V1xD 0x08000000 /* Base VFP instruction set. */ +#define FPU_VFP_EXT_V1 0x04000000 /* Double-precision insns. */ +#define FPU_VFP_EXT_V2 0x02000000 /* ARM10E VFPr1. */ /* Architectures are the sum of the base and extensions. The ARM ARM (rev E) defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T, ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add three more to cover cores prior to ARM6. Finally, there are cores which implement further extensions in the co-processor space. */ -#define ARM_ARCH_V1 ARM_EXT_V1 -#define ARM_ARCH_V2 (ARM_ARCH_V1 | ARM_EXT_V2) -#define ARM_ARCH_V2S (ARM_ARCH_V2 | ARM_EXT_V2S) -#define ARM_ARCH_V3 (ARM_ARCH_V2S | ARM_EXT_V3) -#define ARM_ARCH_V3M (ARM_ARCH_V3 | ARM_EXT_V3M) -#define ARM_ARCH_V4xM (ARM_ARCH_V3 | ARM_EXT_V4) -#define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_V4) -#define ARM_ARCH_V4TxM (ARM_ARCH_V4xM | ARM_EXT_V4T) -#define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_V4T) -#define ARM_ARCH_V5xM (ARM_ARCH_V4xM | ARM_EXT_V5) -#define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5) -#define ARM_ARCH_V5TxM (ARM_ARCH_V5xM | ARM_EXT_V4T | ARM_EXT_V5T) -#define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_V4T | ARM_EXT_V5T) -#define ARM_ARCH_V5TExP (ARM_ARCH_V5T | ARM_EXT_V5ExP) -#define ARM_ARCH_V5TE (ARM_ARCH_V5TExP | ARM_EXT_V5E) -#define ARM_ARCH_V5TEJ (ARM_ARCH_V5TE | ARM_EXT_V5J) -#define ARM_ARCH_V6 (ARM_ARCH_V5TEJ | ARM_EXT_V6) -#define ARM_ARCH_V6K (ARM_ARCH_V6 | ARM_EXT_V6K) -#define ARM_ARCH_V6Z (ARM_ARCH_V6 | ARM_EXT_V6Z) -#define ARM_ARCH_V6ZK (ARM_ARCH_V6 | ARM_EXT_V6K | ARM_EXT_V6Z) -#define ARM_ARCH_V6T2 (ARM_ARCH_V6 | ARM_EXT_V6T2) -#define ARM_ARCH_V6KT2 (ARM_ARCH_V6 | ARM_EXT_V6T2 | ARM_EXT_V6K) -#define ARM_ARCH_V6ZT2 (ARM_ARCH_V6 | ARM_EXT_V6T2 | ARM_EXT_V6Z) -#define ARM_ARCH_V6ZKT2 (ARM_ARCH_V6 | ARM_EXT_V6T2 | ARM_EXT_V6K | ARM_EXT_V6Z) +#define ARM_AEXT_V1 ARM_EXT_V1 +#define ARM_AEXT_V2 (ARM_AEXT_V1 | ARM_EXT_V2) +#define ARM_AEXT_V2S (ARM_AEXT_V2 | ARM_EXT_V2S) +#define ARM_AEXT_V3 (ARM_AEXT_V2S | ARM_EXT_V3) +#define ARM_AEXT_V3M (ARM_AEXT_V3 | ARM_EXT_V3M) +#define ARM_AEXT_V4xM (ARM_AEXT_V3 | ARM_EXT_V4) +#define ARM_AEXT_V4 (ARM_AEXT_V3M | ARM_EXT_V4) +#define ARM_AEXT_V4TxM (ARM_AEXT_V4xM | ARM_EXT_V4T) +#define ARM_AEXT_V4T (ARM_AEXT_V4 | ARM_EXT_V4T) +#define ARM_AEXT_V5xM (ARM_AEXT_V4xM | ARM_EXT_V5) +#define ARM_AEXT_V5 (ARM_AEXT_V4 | ARM_EXT_V5) +#define ARM_AEXT_V5TxM (ARM_AEXT_V5xM | ARM_EXT_V4T | ARM_EXT_V5T) +#define ARM_AEXT_V5T (ARM_AEXT_V5 | ARM_EXT_V4T | ARM_EXT_V5T) +#define ARM_AEXT_V5TExP (ARM_AEXT_V5T | ARM_EXT_V5ExP) +#define ARM_AEXT_V5TE (ARM_AEXT_V5TExP | ARM_EXT_V5E) +#define ARM_AEXT_V5TEJ (ARM_AEXT_V5TE | ARM_EXT_V5J) +#define ARM_AEXT_V6 (ARM_AEXT_V5TEJ | ARM_EXT_V6) +#define ARM_AEXT_V6K (ARM_AEXT_V6 | ARM_EXT_V6K) +#define ARM_AEXT_V6Z (ARM_AEXT_V6 | ARM_EXT_V6Z) +#define ARM_AEXT_V6ZK (ARM_AEXT_V6 | ARM_EXT_V6K | ARM_EXT_V6Z) +#define ARM_AEXT_V6T2 (ARM_AEXT_V6 | ARM_EXT_V6T2) +#define ARM_AEXT_V6KT2 (ARM_AEXT_V6 | ARM_EXT_V6T2 | ARM_EXT_V6K) +#define ARM_AEXT_V6ZT2 (ARM_AEXT_V6 | ARM_EXT_V6T2 | ARM_EXT_V6Z) +#define ARM_AEXT_V6ZKT2 (ARM_AEXT_V6 | ARM_EXT_V6T2 | ARM_EXT_V6K | ARM_EXT_V6Z) /* Processors with specific extensions in the co-processor space. */ -#define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_CEXT_XSCALE) -#define ARM_ARCH_IWMMXT (ARM_ARCH_XSCALE | ARM_CEXT_IWMMXT) +#define ARM_ARCH_XSCALE ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE) +#define ARM_ARCH_IWMMXT \ + ARM_FEATURE (ARM_AEXT_V5TE, ARM_CEXT_XSCALE | ARM_CEXT_IWMMXT) + +#define FPU_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_ENDIAN_PURE) +#define FPU_VFP_V1 (FPU_VFP_V1xD | FPU_VFP_EXT_V1) +#define FPU_VFP_V2 (FPU_VFP_V1 | FPU_VFP_EXT_V2) +#define FPU_VFP_HARD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_V1 | FPU_VFP_EXT_V2) +#define FPU_FPA (FPU_FPA_EXT_V1 | FPU_FPA_EXT_V2) + +/* Deprecated */ +#define FPU_ARCH_VFP ARM_FEATURE (0, FPU_ENDIAN_PURE) -#define FPU_FPA_EXT_V1 0x80000000 /* Base FPA instruction set. */ -#define FPU_FPA_EXT_V2 0x40000000 /* LFM/SFM. */ -#define FPU_VFP_EXT_NONE 0x20000000 /* Use VFP word-ordering. */ -#define FPU_VFP_EXT_V1xD 0x10000000 /* Base VFP instruction set. */ -#define FPU_VFP_EXT_V1 0x08000000 /* Double-precision insns. */ -#define FPU_VFP_EXT_V2 0x04000000 /* ARM10E VFPr1. */ -#define FPU_MAVERICK 0x02000000 /* Cirrus Maverick. */ -#define FPU_NONE 0 +#define FPU_ARCH_FPE ARM_FEATURE (0, FPU_FPA_EXT_V1) +#define FPU_ARCH_FPA ARM_FEATURE (0, FPU_FPA) -#define FPU_ARCH_FPE FPU_FPA_EXT_V1 -#define FPU_ARCH_FPA (FPU_ARCH_FPE | FPU_FPA_EXT_V2) +#define FPU_ARCH_VFP_V1xD ARM_FEATURE (0, FPU_VFP_V1xD) +#define FPU_ARCH_VFP_V1 ARM_FEATURE (0, FPU_VFP_V1) +#define FPU_ARCH_VFP_V2 ARM_FEATURE (0, FPU_VFP_V2) +#define FPU_ARCH_VFP_HARD ARM_FEATURE (0, FPU_VFP_HARD) -#define FPU_ARCH_VFP FPU_VFP_EXT_NONE -#define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE) -#define FPU_ARCH_VFP_V1 (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1) -#define FPU_ARCH_VFP_V2 (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2) +#define FPU_ARCH_ENDIAN_PURE ARM_FEATURE (0, FPU_ENDIAN_PURE) -#define FPU_ARCH_MAVERICK FPU_MAVERICK +#define FPU_ARCH_MAVERICK ARM_FEATURE (0, FPU_MAVERICK) + +#define ARM_ARCH_V1 ARM_FEATURE (ARM_AEXT_V1, 0) +#define ARM_ARCH_V2 ARM_FEATURE (ARM_AEXT_V2, 0) +#define ARM_ARCH_V2S ARM_FEATURE (ARM_AEXT_V2S, 0) +#define ARM_ARCH_V3 ARM_FEATURE (ARM_AEXT_V3, 0) +#define ARM_ARCH_V3M ARM_FEATURE (ARM_AEXT_V3M, 0) +#define ARM_ARCH_V4xM ARM_FEATURE (ARM_AEXT_V4xM, 0) +#define ARM_ARCH_V4 ARM_FEATURE (ARM_AEXT_V4, 0) +#define ARM_ARCH_V4TxM ARM_FEATURE (ARM_AEXT_V4TxM, 0) +#define ARM_ARCH_V4T ARM_FEATURE (ARM_AEXT_V4T, 0) +#define ARM_ARCH_V5xM ARM_FEATURE (ARM_AEXT_V5xM, 0) +#define ARM_ARCH_V5 ARM_FEATURE (ARM_AEXT_V5, 0) +#define ARM_ARCH_V5TxM ARM_FEATURE (ARM_AEXT_V5TxM, 0) +#define ARM_ARCH_V5T ARM_FEATURE (ARM_AEXT_V5T, 0) +#define ARM_ARCH_V5TExP ARM_FEATURE (ARM_AEXT_V5TExP, 0) +#define ARM_ARCH_V5TE ARM_FEATURE (ARM_AEXT_V5TE, 0) +#define ARM_ARCH_V5TEJ ARM_FEATURE (ARM_AEXT_V5TEJ, 0) +#define ARM_ARCH_V6 ARM_FEATURE (ARM_AEXT_V6, 0) +#define ARM_ARCH_V6K ARM_FEATURE (ARM_AEXT_V6K, 0) +#define ARM_ARCH_V6Z ARM_FEATURE (ARM_AEXT_V6Z, 0) +#define ARM_ARCH_V6ZK ARM_FEATURE (ARM_AEXT_V6ZK, 0) +#define ARM_ARCH_V6T2 ARM_FEATURE (ARM_AEXT_V6T2, 0) +#define ARM_ARCH_V6KT2 ARM_FEATURE (ARM_AEXT_V6KT2, 0) +#define ARM_ARCH_V6ZT2 ARM_FEATURE (ARM_AEXT_V6ZT2, 0) +#define ARM_ARCH_V6ZKT2 ARM_FEATURE (ARM_AEXT_V6ZKT2, 0) /* Some useful combinations: */ -#define ARM_ANY 0x0000ffff /* Any basic core. */ -#define ARM_ALL 0x00ffffff /* Any core + co-processor */ -#define CPROC_ANY 0x00ff0000 /* Any co-processor */ -#define FPU_ANY 0xff000000 /* Note this is ~ARM_ALL. */ +#define ARM_ARCH_NONE ARM_FEATURE (0, 0) +#define FPU_NONE ARM_FEATURE (0, 0) +#define ARM_ANY ARM_FEATURE (-1, 0) /* Any basic core. */ +#define FPU_ANY_HARD ARM_FEATURE (0, FPU_FPA | FPU_VFP_HARD | FPU_MAVERICK) +#define ARM_ARCH_THUMB2 ARM_FEATURE (ARM_EXT_V6T2, 0) + +/* There are too many feature bits to fit in a single word, so use a + structure. For simplicity we put all core features in one word and + everything else in the other. */ +typedef struct +{ + unsigned long core; + unsigned long coproc; +} arm_feature_set; + +#define ARM_CPU_HAS_FEATURE(CPU,FEAT) \ + (((CPU).core & (FEAT).core) != 0 || ((CPU).coproc & (FEAT).coproc) != 0) + +#define ARM_MERGE_FEATURE_SETS(TARG,F1,F2) \ + do { \ + (TARG).core = (F1).core | (F2).core; \ + (TARG).coproc = (F1).coproc | (F2).coproc; \ + } while (0) + +#define ARM_CLEAR_FEATURE(TARG,F1,F2) \ + do { \ + (TARG).core = (F1).core &~ (F2).core; \ + (TARG).coproc = (F1).coproc &~ (F2).coproc; \ + } while (0) + +#define ARM_FEATURE(core, coproc) {(core), (coproc)} -- 2.30.2