diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 14 | ||||
-rw-r--r-- | gas/config/tc-arm.c | 76 |
2 files changed, 60 insertions, 30 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index a7ceb30..8a62482 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +2015-12-24 Thomas Preud'homme <thomas.preudhomme@arm.com> + + * config/tc-arm.c (move_or_literal_pool): Check mov.w, mvm and movw + availability against arm_ext_v6t2 instead of checking arm_arch_t2, + fixing comments along the way. + (handle_it_state): Check arm_ext_v6t2 instead of arm_arch_t2 to + generate IT instruction. + (t1_isa_t32_only_insn): New function. + (md_assemble): Use above new function to check for invalid wide + instruction for CPU Thumb ISA and to determine what Thumb extension + bit is necessary for that instruction. + (md_apply_fix): Use arm_ext_v6t2 instead of arm_arch_t2 to decide if + branch is out of range. + 2015-12-21 Nick Clifton <nickc@redhat.com> PR gas/19386 diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index f9c76ef..23e3506 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -7869,10 +7869,10 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3) return TRUE; } - if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_arch_t2)) + if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)) { - /* Check if on thumb2 it can be done with a mov.w or mvn.w - instruction. */ + /* Check if on thumb2 it can be done with a mov.w, mvn or + movw instruction. */ unsigned int newimm; bfd_boolean isNegated; @@ -7886,19 +7886,22 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3) isNegated = TRUE; } + /* The number can be loaded with a mov.w or mvn + instruction. */ if (newimm != (unsigned int) FAIL) { - inst.instruction = (0xf04f0000 + inst.instruction = (0xf04f0000 /* MOV.W. */ | (inst.operands[i].reg << 8)); + /* Change to MOVN. */ inst.instruction |= (isNegated ? 0x200000 : 0); inst.instruction |= (newimm & 0x800) << 15; inst.instruction |= (newimm & 0x700) << 4; inst.instruction |= (newimm & 0x0ff); return TRUE; } + /* The number can be loaded with a movw instruction. */ else if ((v & ~0xFFFF) == 0) { - /* The number can be loaded with a mov.w instruction. */ int imm = v & 0xFFFF; inst.instruction = 0xf2400000; /* MOVW. */ @@ -17563,7 +17566,7 @@ handle_it_state (void) else { if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB) - && ARM_CPU_HAS_FEATURE (cpu_variant, arm_arch_t2)) + && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)) { /* Automatically generate the IT instruction. */ new_automatic_it_block (inst.cond); @@ -17795,6 +17798,22 @@ in_it_block (void) return now_it.state != OUTSIDE_IT_BLOCK; } +/* Whether OPCODE only has T32 encoding and makes build attribute + Tag_THUMB_ISA_use be set to 1 if assembled without any cpu or arch info. */ + +static bfd_boolean +t1_isa_t32_only_insn (const struct asm_opcode *opcode) +{ + /* 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; + + return FALSE; +} + void md_assemble (char *str) { @@ -17854,24 +17873,24 @@ md_assemble (char *str) 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) + && !t1_isa_t32_only_insn (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; - } + as_bad (_("selected processor does not support `%s' in Thumb-2 " + "mode"), str); + return; } } @@ -17906,13 +17925,10 @@ md_assemble (char *str) 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 (inst.size == 4 && !t1_isa_t32_only_insn (opcode)) ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, arm_ext_v6t2); @@ -22880,7 +22896,7 @@ md_apply_fix (fixS * fixP, if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff)) { - if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_arch_t2))) + if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))) as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE); else if ((value & ~0x1ffffff) && ((value & ~0x1ffffff) != ~0x1ffffff)) |