diff options
author | Thomas Preud'homme <thomas.preudhomme@arm.com> | 2015-12-24 17:01:42 +0800 |
---|---|---|
committer | Thomas Preud'homme <thomas.preudhomme@arm.com> | 2015-12-24 17:03:50 +0800 |
commit | fc289b0a832c536a2ec324634cb420f39b212696 (patch) | |
tree | 3e5e7105c3ab6ae8d8723d4367db1127079713ab | |
parent | 443bfd5a371633064bf251a74b27382c7774f217 (diff) | |
download | fsf-binutils-gdb-fc289b0a832c536a2ec324634cb420f39b212696.zip fsf-binutils-gdb-fc289b0a832c536a2ec324634cb420f39b212696.tar.gz fsf-binutils-gdb-fc289b0a832c536a2ec324634cb420f39b212696.tar.bz2 |
Consolidate Thumb-1/Thumb-2 ISA detection
2015-12-24 Thomas Preud'homme <thomas.preudhomme@arm.com>
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.
-rw-r--r-- | gas/ChangeLog | 14 | ||||
-rw-r--r-- | gas/config/tc-arm.c | 76 | ||||
-rw-r--r-- | include/opcode/ChangeLog | 5 | ||||
-rw-r--r-- | 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 <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)) 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 <thomas.preudhomme@arm.com> + + * 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 <matthew.wahab@arm.com> * 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. */ |