From: Thomas Preud'homme Date: Tue, 29 Mar 2016 16:51:56 +0000 (+0100) Subject: Merge FSF binutils-2_26-branch X-Git-Tag: users/ARM/embedded-binutils-2_26-branch-2016q1~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=753be8b6191133f28222fc45b406aebfdd03dd11;p=thirdparty%2Fbinutils-gdb.git Merge FSF binutils-2_26-branch Merge changes made in FSF binutils-2_26-branch since last GCC ARM embedded release. --- 753be8b6191133f28222fc45b406aebfdd03dd11 diff --cc bfd/elf32-arm.c index 7ad8de48c16,5affc76bfdb..3a4923d340f --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@@ -3445,10 -3445,20 +3445,23 @@@ create_ifunc_sections (struct bfd_link_ static bfd_boolean using_thumb_only (struct elf32_arm_link_hash_table *globals) { - int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, - Tag_CPU_arch); - int profile; ++ int arch; + int profile = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, + Tag_CPU_arch_profile); - return profile == 'M'; - if (arch == TAG_CPU_ARCH_V6_M || arch == TAG_CPU_ARCH_V6S_M) - return TRUE; ++ if (profile) ++ return profile == 'M'; + - if (arch != TAG_CPU_ARCH_V7 && arch != TAG_CPU_ARCH_V7E_M) - return FALSE; ++ arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch); + - profile = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, - Tag_CPU_arch_profile); ++ if (arch == TAG_CPU_ARCH_V6_M ++ || arch == TAG_CPU_ARCH_V6S_M ++ || arch == TAG_CPU_ARCH_V7E_M ++ || arch == TAG_CPU_ARCH_V8M_BASE ++ || arch == TAG_CPU_ARCH_V8M_MAIN) ++ return TRUE; + - return profile == 'M'; ++ return FALSE; } /* Determine if we're dealing with a Thumb-2 object. */ @@@ -12176,47 -12186,6 +12189,47 @@@ tag_cpu_arch_combine (bfd *ibfd, int ol T(V8), /* V7E_M. */ T(V8) /* V8. */ }; + const int v8m_baseline[] = + { + -1, /* PRE_V4. */ + -1, /* V4. */ + -1, /* V4T. */ + -1, /* V5T. */ + -1, /* V5TE. */ + -1, /* V5TEJ. */ + -1, /* V6. */ + -1, /* V6KZ. */ + -1, /* V6T2. */ + -1, /* V6K. */ + -1, /* V7. */ + T(V8M_BASE), /* V6_M. */ + T(V8M_BASE), /* V6S_M. */ + -1, /* V7E_M. */ + -1, /* V8. */ + -1, - T(V8M_BASE), /* V8-M BASELINE. */ ++ T(V8M_BASE) /* V8-M BASELINE. */ + }; + const int v8m_mainline[] = + { + -1, /* PRE_V4. */ + -1, /* V4. */ + -1, /* V4T. */ + -1, /* V5T. */ + -1, /* V5TE. */ + -1, /* V5TEJ. */ + -1, /* V6. */ + -1, /* V6KZ. */ + -1, /* V6T2. */ + -1, /* V6K. */ + T(V8M_MAIN), /* V7. */ + T(V8M_MAIN), /* V6_M. */ + T(V8M_MAIN), /* V6S_M. */ + T(V8M_MAIN), /* V7E_M. */ + -1, /* V8. */ + -1, + T(V8M_MAIN), /* V8-M BASELINE. */ - T(V8M_MAIN), /* V8-M MAINLINE. */ ++ T(V8M_MAIN) /* V8-M MAINLINE. */ + }; const int v4t_plus_v6_m[] = { -1, /* PRE_V4. */ @@@ -12234,9 -12203,7 +12247,10 @@@ T(V6S_M), /* V6S_M. */ T(V7E_M), /* V7E_M. */ T(V8), /* V8. */ - T(V4T_PLUS_V6_M), /* V4T plus V6_M. */ - -1, /* V8-M BASELINE. */ - -1 /* V8-M MAINLINE. */ ++ -1, /* Unused. */ ++ T(V8M_BASE), /* V8-M BASELINE. */ ++ T(V8M_MAIN), /* V8-M MAINLINE. */ + T(V4T_PLUS_V6_M) /* V4T plus V6_M. */ }; const int *comb[] = { @@@ -12247,9 -12214,8 +12261,11 @@@ v6s_m, v7e_m, v8, - v4t_plus_v6_m, /* Pseudo-architecture. */ ++ NULL, + v8m_baseline, + v8m_mainline, + /* Pseudo-architecture. */ + v4t_plus_v6_m }; /* Check we've not got a higher architecture than we know about. */ @@@ -12280,7 -12246,7 +12296,7 @@@ if (tagh <= TAG_CPU_ARCH_V6KZ) return result; -- result = comb[tagh - T(V6T2)][tagl]; ++ result = comb[tagh - T(V6T2)] ? comb[tagh - T(V6T2)][tagl] : -1; /* Use Tag_CPU_arch == V4T and Tag_also_compatible_with (Tag_CPU_arch V6_M) as the canonical version. */ diff --cc gas/config/tc-arm.c index 72acd5f15f3,3bd4bc9f81c..25a91d4eb4c --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@@ -17793,55 -17767,6 +17793,56 @@@ in_it_block (void return now_it.state != OUTSIDE_IT_BLOCK; } - /* Given an OPCODE that is valid in at least one architecture that is not a - superset of ARMv6t2, returns whether it only has wide encoding(s). */ ++/* Whether OPCODE only has T32 encoding. Since this function is only used by ++ t32_insn_ok, OPCODE enabled by v6t2 extension bit do not need to be listed ++ here, hence the "known" in the function name. */ + +static bfd_boolean - non_v6t2_wide_only_insn (const struct asm_opcode *opcode) ++known_t32_only_insn (const struct asm_opcode *opcode) +{ - /* Wide instruction that have always been in Thumb-1 ISA. */ ++ /* Original Thumb-1 wide instruction. */ + if (opcode->tencode == do_t_blx + || opcode->tencode == do_t_branch23 + || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr) + || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier)) + return TRUE; + + /* Wide-only instruction added to ARMv8-M. */ + if (ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v8m) + || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_atomics) + || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v6t2_v8m) + || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_div)) + return TRUE; + + return FALSE; +} + +/* Whether wide instruction variant can be used if available for a valid OPCODE + in ARCH. */ + +static bfd_boolean - wide_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode) ++t32_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode) +{ - if (non_v6t2_wide_only_insn (opcode)) ++ if (known_t32_only_insn (opcode)) + return TRUE; + + /* Instruction with narrow and wide encoding added to ARMv8-M. Availability + of variant T3 of B.W is checked in do_t_branch. */ + if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m) + && opcode->tencode == do_t_branch) + return TRUE; + + /* Wide instruction variants of all instructions with narrow *and* wide + variants become available with ARMv6t2. Other opcodes are either + narrow-only or wide-only and are thus available if OPCODE is valid. */ + if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v6t2)) + return TRUE; + + /* OPCODE with narrow only instruction variant or wide variant not + available. */ + return FALSE; +} + void md_assemble (char *str) { @@@ -17901,28 -17826,24 +17902,28 @@@ return; } - if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2)) + /* Two things are addressed here: + 1) Implicit require narrow instructions on Thumb-1. + This avoids relaxation accidentally introducing Thumb-2 + instructions. + 2) Reject wide instructions in non Thumb-2 cores. + + Only instructions with narrow and wide variants need to be handled + but selecting all non wide-only instructions is easier. */ + if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2) - && !wide_insn_ok (variant, opcode)) ++ && !t32_insn_ok (variant, opcode)) { - if (opcode->tencode != do_t_blx && opcode->tencode != do_t_branch23 - && !(ARM_CPU_HAS_FEATURE(*opcode->tvariant, arm_ext_msr) - || ARM_CPU_HAS_FEATURE(*opcode->tvariant, arm_ext_barrier))) + if (inst.size_req == 0) + inst.size_req = 2; + else if (inst.size_req == 4) { - /* Two things are addressed here. - 1) Implicit require narrow instructions on Thumb-1. - This avoids relaxation accidentally introducing Thumb-2 - instructions. - 2) Reject wide instructions in non Thumb-2 cores. */ - if (inst.size_req == 0) - inst.size_req = 2; - else if (inst.size_req == 4) - { - as_bad (_("selected processor does not support `%s' in Thumb-2 mode"), str); - return; - } + if (ARM_CPU_HAS_FEATURE (variant, arm_ext_v8m)) + as_bad (_("selected processor does not support 32bit wide " + "variant of instruction `%s'"), str); + else + as_bad (_("selected processor does not support `%s' in " + "Thumb-2 mode"), str); + return; } } @@@ -17957,14 -17878,13 +17958,14 @@@ 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 instructions are seen. ie. - anything other than bl/blx and v6-M instructions. - The impact of relaxable instructions will be considered later after we - finish all relaxation. */ - if ((inst.size == 4 && (inst.instruction & 0xf800e800) != 0xf000e800) - && !(ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr) - || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier))) + set those bits when Thumb-2 32-bit instructions are seen. The impact + of relaxable instructions will be considered later after we finish all + relaxation. */ + if (ARM_FEATURE_CORE_EQUAL (cpu_variant, arm_arch_any)) + variant = arm_arch_none; + else + variant = cpu_variant; - if (inst.size == 4 && !wide_insn_ok (variant, opcode)) ++ if (inst.size == 4 && !t32_insn_ok (variant, opcode)) ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, arm_ext_v6t2); @@@ -25656,30 -25521,11 +25657,31 @@@ aeabi_set_public_attributes (void actually used. Perhaps we should separate out the specified and implicit cases. Avoid taking this path for -march=all by checking for contradictory v7-A / v7-M features. */ -- if (arch == 10 ++ if (arch == TAG_CPU_ARCH_V7 && !ARM_CPU_HAS_FEATURE (flags, arm_ext_v7a) && ARM_CPU_HAS_FEATURE (flags, arm_ext_v7m) && ARM_CPU_HAS_FEATURE (flags, arm_ext_v6_dsp)) - arch = 13; + { - arch = 13; ++ arch = TAG_CPU_ARCH_V7E_M; + arm_arch = (arm_feature_set) ARM_ARCH_V7EM; + } + + ARM_CLEAR_FEATURE (tmp, flags, arm_arch_v8m_base); - if (arch == 16 && ARM_CPU_HAS_FEATURE (tmp, arm_arch_any)) ++ if (arch == TAG_CPU_ARCH_V8M_BASE && ARM_CPU_HAS_FEATURE (tmp, arm_arch_any)) + { - arch = 17; ++ arch = TAG_CPU_ARCH_V8M_MAIN; + arm_arch = (arm_feature_set) ARM_ARCH_V8M_MAIN; + } + + /* In cpu_arch_ver ARMv8-A is before ARMv8-M for atomics to be detected as + coming from ARMv8-A. However, since ARMv8-A has more instructions than + ARMv8-M, -march=all must be detected as ARMv8-A. */ - if (arch == 17 && ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any)) ++ if (arch == TAG_CPU_ARCH_V8M_MAIN ++ && ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any)) + { - arch = 14; ++ arch = TAG_CPU_ARCH_V8; + arm_arch = (arm_feature_set) ARM_ARCH_V8A; + } /* Tag_CPU_name. */ if (selected_cpu_name[0]) diff --cc include/elf/arm.h index a477f17dd8c,c64e7886e92..63c5aacf143 --- a/include/elf/arm.h +++ b/include/elf/arm.h @@@ -105,12 -105,10 +105,12 @@@ #define TAG_CPU_ARCH_V6S_M 12 #define TAG_CPU_ARCH_V7E_M 13 #define TAG_CPU_ARCH_V8 14 -#define MAX_TAG_CPU_ARCH 14 +#define TAG_CPU_ARCH_V8M_BASE 16 +#define TAG_CPU_ARCH_V8M_MAIN 17 +#define MAX_TAG_CPU_ARCH TAG_CPU_ARCH_V8M_MAIN /* Pseudo-architecture to allow objects to be compatible with the subset of armv4t and armv6-m. This value should never be stored in object files. */ - #define TAG_CPU_ARCH_V4T_PLUS_V6_M 15 + #define TAG_CPU_ARCH_V4T_PLUS_V6_M (MAX_TAG_CPU_ARCH + 1) /* Relocation types. */ diff --cc include/opcode/arm.h index d6489ae3ef4,0cb4d57d112..e9cde31768a --- a/include/opcode/arm.h +++ b/include/opcode/arm.h @@@ -33,8 -33,8 +33,7 @@@ #define ARM_EXT_V5J 0x00000800 /* Jazelle extension. */ #define ARM_EXT_V6 0x00001000 /* ARM V6. */ #define ARM_EXT_V6K 0x00002000 /* ARM V6K. */ --/* 0x00004000 Was ARM V6Z. */ - #define ARM_EXT_V8 0x00004000 /* is now ARMv8 w/o atomics. */ -#define ARM_EXT_V8 0x00004000 /* is now ARMv8. */ ++#define ARM_EXT_V8 0x00004000 /* ARMv8 w/o atomics. */ #define ARM_EXT_V6T2 0x00008000 /* Thumb-2. */ #define ARM_EXT_DIV 0x00010000 /* Integer division. */ /* The 'M' in Arm V7M stands for Microcontroller. @@@ -245,22 -237,20 +244,23 @@@ #define ARM_ARCH_V6K ARM_FEATURE_CORE_LOW (ARM_AEXT_V6K) #define ARM_ARCH_V6Z ARM_FEATURE_CORE_LOW (ARM_AEXT_V6Z) #define ARM_ARCH_V6KZ ARM_FEATURE_CORE_LOW (ARM_AEXT_V6KZ) -#define ARM_ARCH_V6T2 ARM_FEATURE_CORE_LOW (ARM_AEXT_V6T2) -#define ARM_ARCH_V6KT2 ARM_FEATURE_CORE_LOW (ARM_AEXT_V6KT2) -#define ARM_ARCH_V6ZT2 ARM_FEATURE_CORE_LOW (ARM_AEXT_V6ZT2) -#define ARM_ARCH_V6KZT2 ARM_FEATURE_CORE_LOW (ARM_AEXT_V6KZT2) +#define ARM_ARCH_V6T2 ARM_FEATURE_CORE (ARM_AEXT_V6T2, ARM_EXT2_V6T2_V8M) +#define ARM_ARCH_V6KT2 ARM_FEATURE_CORE (ARM_AEXT_V6KT2, ARM_EXT2_V6T2_V8M) +#define ARM_ARCH_V6ZT2 ARM_FEATURE_CORE (ARM_AEXT_V6ZT2, ARM_EXT2_V6T2_V8M) +#define ARM_ARCH_V6KZT2 ARM_FEATURE_CORE (ARM_AEXT_V6KZT2, ARM_EXT2_V6T2_V8M) #define ARM_ARCH_V6M ARM_FEATURE_CORE_LOW (ARM_AEXT_V6M) #define ARM_ARCH_V6SM ARM_FEATURE_CORE_LOW (ARM_AEXT_V6SM) -#define ARM_ARCH_V7 ARM_FEATURE_CORE_LOW (ARM_AEXT_V7) -#define ARM_ARCH_V7A ARM_FEATURE_CORE_LOW (ARM_AEXT_V7A) -#define ARM_ARCH_V7VE ARM_FEATURE_CORE_LOW (ARM_AEXT_V7VE) -#define ARM_ARCH_V7R ARM_FEATURE_CORE_LOW (ARM_AEXT_V7R) -#define ARM_ARCH_V7M ARM_FEATURE_CORE_LOW (ARM_AEXT_V7M) -#define ARM_ARCH_V7EM ARM_FEATURE_CORE_LOW (ARM_AEXT_V7EM) -#define ARM_ARCH_V8A ARM_FEATURE_CORE_LOW (ARM_AEXT_V8A) -#define ARM_ARCH_V8_1A ARM_FEATURE_CORE (ARM_AEXT_V8A, ARM_EXT2_PAN) +#define ARM_ARCH_V7 ARM_FEATURE_CORE (ARM_AEXT_V7, ARM_EXT2_V6T2_V8M) +#define ARM_ARCH_V7A ARM_FEATURE_CORE (ARM_AEXT_V7A, ARM_EXT2_V6T2_V8M) +#define ARM_ARCH_V7VE ARM_FEATURE_CORE (ARM_AEXT_V7VE, ARM_EXT2_V6T2_V8M) +#define ARM_ARCH_V7R ARM_FEATURE_CORE (ARM_AEXT_V7R, ARM_EXT2_V6T2_V8M) +#define ARM_ARCH_V7M ARM_FEATURE_CORE (ARM_AEXT_V7M, ARM_EXT2_V6T2_V8M) +#define ARM_ARCH_V7EM ARM_FEATURE_CORE (ARM_AEXT_V7EM, ARM_EXT2_V6T2_V8M) +#define ARM_ARCH_V8A ARM_FEATURE_CORE (ARM_AEXT_V8A, ARM_AEXT2_V8A) - #define ARM_ARCH_V8_1A ARM_FEATURE_CORE (ARM_AEXT_V8A, ARM_AEXT2_V8_1A) ++#define ARM_ARCH_V8_1A ARM_FEATURE (ARM_AEXT_V8A, ARM_AEXT2_V8_1A, \ ++ CRC_EXT_ARMV8) +#define ARM_ARCH_V8M_BASE ARM_FEATURE_CORE (ARM_AEXT_V8M_BASE, ARM_AEXT2_V8M) +#define ARM_ARCH_V8M_MAIN ARM_FEATURE_CORE (ARM_AEXT_V8M_MAIN, ARM_AEXT2_V8M) /* Some useful combinations: */ #define ARM_ARCH_NONE ARM_FEATURE_LOW (0, 0)