From fc289b0a832c536a2ec324634cb420f39b212696 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 24 Dec 2015 17:01:42 +0800 Subject: [PATCH] Consolidate Thumb-1/Thumb-2 ISA detection 2015-12-24 Thomas Preud'homme gas/ * 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. include/opcode/ * arm.h (ARM_ARCH_THUMB2): Add comment explaining its meaning and remove extension bit not including any Thumb-2 instruction. --- gas/ChangeLog | 14 +++++++++ gas/config/tc-arm.c | 76 +++++++++++++++++++++++++++++------------------- include/opcode/ChangeLog | 5 ++++ include/opcode/arm.h | 6 ++-- 4 files changed, 68 insertions(+), 33 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 + + * 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 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)) diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index ca7492b..e0d3f26 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,8 @@ +2015-12-24 Thomas Preud'homme + + * arm.h (ARM_ARCH_THUMB2): Add comment explaining its meaning and + remove extension bit not including any Thumb-2 instruction. + 2015-12-15 Matthew Wahab * arm.h (ARM_ARCH_V8_1A): Add the CRC_EXT_ARMV8 co-processor diff --git a/include/opcode/arm.h b/include/opcode/arm.h index daeb626..eb0619c 100644 --- a/include/opcode/arm.h +++ b/include/opcode/arm.h @@ -263,10 +263,10 @@ #define ARM_ANY ARM_FEATURE (-1, -1, 0) /* Any basic core. */ #define ARM_FEATURE_ALL ARM_FEATURE (-1, -1, -1)/* All CPU and FPU features. */ #define FPU_ANY_HARD ARM_FEATURE_COPROC (FPU_FPA | FPU_VFP_HARD | FPU_MAVERICK) +/* Extensions containing some Thumb-2 instructions. If any is present, Thumb + ISA is Thumb-2. */ #define ARM_ARCH_THUMB2 ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2 | ARM_EXT_V7 \ - | ARM_EXT_V7A | ARM_EXT_V7R \ - | ARM_EXT_V7M | ARM_EXT_DIV \ - | ARM_EXT_V8) + | ARM_EXT_DIV | ARM_EXT_V8) /* v7-a+sec. */ #define ARM_ARCH_V7A_SEC ARM_FEATURE_CORE_LOW (ARM_AEXT_V7A | ARM_EXT_SEC) /* v7-a+mp+sec. */ -- 2.7.4